mirror of https://github.com/wb2osz/direwolf.git
Assorted minor cleanups.
This commit is contained in:
parent
397362787f
commit
07ea828c28
18
README.md
18
README.md
|
@ -9,7 +9,7 @@ Why waste $200 and settle for mediocre receive performance from a 1980's technol
|
|||
|
||||
![](tnc-test-cd-results.png)
|
||||
|
||||
Dire Wolf now includes [FX.25](https://en.wikipedia.org/wiki/FX.25_Forward_Error_Correction) which adds Forward Error Correction (FEC) in a way that is completely compatible with existing systems. If both ends are capable of FX.25, your information will continue to get through under conditions where regular AX.25 is completely useless.
|
||||
Dire Wolf now includes [FX.25](https://en.wikipedia.org/wiki/FX.25_Forward_Error_Correction) which adds Forward Error Correction (FEC) in a way that is completely compatible with existing systems. If both ends are capable of FX.25, your information will continue to get through under conditions where regular AX.25 is completely useless. This was originally developed for satellites and is now seeing widespread use on HF.
|
||||
|
||||
![](fx25.png)
|
||||
|
||||
|
@ -80,7 +80,21 @@ It can also be used as a virtual TNC for other applications such as [APRSIS32](h
|
|||
|
||||
|
||||
|
||||
- **Standard 300, 1200 & 9600 bps modems and more.**
|
||||
- **Modems:**
|
||||
|
||||
300 bps AFSK for HF
|
||||
|
||||
1200 bps AFSK most common for VHF/UHF
|
||||
|
||||
2400 & 4800 bps PSK
|
||||
|
||||
9600 bps GMSK/G3RUH
|
||||
|
||||
AIS reception
|
||||
|
||||
EAS SAME reception
|
||||
|
||||
|
||||
|
||||
- **DTMF ("Touch Tone") Decoding and Encoding.**
|
||||
|
||||
|
|
|
@ -369,10 +369,11 @@
|
|||
%W%
|
||||
%C%#
|
||||
%C%# It is sometimes possible to recover frames with a bad FCS.
|
||||
%C%# This applies to all channels.
|
||||
%C%# This is not a global setting.
|
||||
%C%# It applies only the the most recent CHANNEL specified.
|
||||
%C%#
|
||||
%C%# 0 [NONE] - Don't try to repair.
|
||||
%C%# 1 [SINGLE] - Attempt to fix single bit error. (default)
|
||||
%C%# 0 - Don't try to repair.
|
||||
%C%# 1 - Attempt to fix single bit error. (default)
|
||||
%C%# ... see User Guide for more values and in-depth discussion.
|
||||
%C%#
|
||||
%C%
|
||||
|
|
31
src/atest.c
31
src/atest.c
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2019, 2021 John Langner, WB2OSZ
|
||||
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2019, 2021, 2022 John Langner, WB2OSZ
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
|
@ -23,11 +23,11 @@
|
|||
*
|
||||
* Name: atest.c
|
||||
*
|
||||
* Purpose: Test fixture for the AFSK demodulator.
|
||||
* Purpose: Test fixture for the Dire Wolf demodulators.
|
||||
*
|
||||
* Inputs: Takes audio from a .WAV file instead of the audio device.
|
||||
*
|
||||
* Description: This can be used to test the AFSK demodulator under
|
||||
* Description: This can be used to test the demodulators under
|
||||
* controlled and reproducible conditions for tweaking.
|
||||
*
|
||||
* For example
|
||||
|
@ -107,7 +107,7 @@ struct wav_header { /* .WAV file header. */
|
|||
/* 8 bit samples are unsigned bytes */
|
||||
/* in range of 0 .. 255. */
|
||||
|
||||
/* 16 bit samples are signed short */
|
||||
/* 16 bit samples are little endian signed short */
|
||||
/* in range of -32768 .. +32767. */
|
||||
|
||||
static struct {
|
||||
|
@ -765,7 +765,7 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
|
|||
unsigned char *pinfo;
|
||||
int info_len;
|
||||
int h;
|
||||
char heard[AX25_MAX_ADDR_LEN];
|
||||
char heard[2 * AX25_MAX_ADDR_LEN + 20];
|
||||
char alevel_text[AX25_ALEVEL_TO_TEXT_SIZE];
|
||||
|
||||
packets_decoded_one++;
|
||||
|
@ -810,6 +810,23 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
|
|||
}
|
||||
ax25_alevel_to_text (alevel, alevel_text);
|
||||
|
||||
/* As suggested by KJ4ERJ, if we are receiving from */
|
||||
/* WIDEn-0, it is quite likely (but not guaranteed), that */
|
||||
/* we are actually hearing the preceding station in the path. */
|
||||
|
||||
if (h >= AX25_REPEATER_2 &&
|
||||
strncmp(heard, "WIDE", 4) == 0 &&
|
||||
isdigit(heard[4]) &&
|
||||
heard[5] == '\0') {
|
||||
|
||||
char probably_really[AX25_MAX_ADDR_LEN];
|
||||
ax25_get_addr_with_ssid(pp, h-1, probably_really);
|
||||
|
||||
strlcat (heard, " (probably ", sizeof(heard));
|
||||
strlcat (heard, probably_really, sizeof(heard));
|
||||
strlcat (heard, ")", sizeof(heard));
|
||||
}
|
||||
|
||||
if (my_audio_config.achan[chan].fix_bits == RETRY_NONE && my_audio_config.achan[chan].passall == 0) {
|
||||
dw_printf ("%s audio level = %s %s\n", heard, alevel_text, spectrum);
|
||||
}
|
||||
|
@ -877,7 +894,7 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
|
|||
|
||||
|
||||
|
||||
#if 1 // temp experiment TODO: remove this.
|
||||
#if 0 // temp experiment
|
||||
|
||||
#include "decode_aprs.h"
|
||||
#include "log.h"
|
||||
|
@ -886,7 +903,7 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
|
|||
|
||||
decode_aprs_t A;
|
||||
|
||||
decode_aprs (&A, pp, 0, 0);
|
||||
decode_aprs (&A, pp, 0, NULL);
|
||||
|
||||
// Temp experiment to see how different systems set the RR bits in the source and destination.
|
||||
// log_rr_bits (&A, pp);
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
|
||||
#include "audio_stats.h"
|
||||
#include "textcolor.h"
|
||||
#include "dtime_now.h"
|
||||
#include "demod.h" /* for alevel_t & demod_get_audio_level() */
|
||||
|
||||
|
||||
|
|
|
@ -2864,6 +2864,9 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
|
||||
/*
|
||||
* CFILTER from-chan to-chan filter_specification_expression
|
||||
*
|
||||
* Why did I put this here?
|
||||
* What would be a useful use case? Perhaps block by source or destination?
|
||||
*/
|
||||
|
||||
else if (strcasecmp(t, "CFILTER") == 0) {
|
||||
|
|
|
@ -140,10 +140,11 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen);
|
|||
*
|
||||
* quiet - Suppress error messages.
|
||||
*
|
||||
* third_party - True when parsing a third party header.
|
||||
* third_party_src - Specify when parsing a third party header.
|
||||
* (decode_aprs is called recursively.)
|
||||
* This is mostly found when an IGate transmits a message
|
||||
* that came via APRS-IS.
|
||||
* NULL when not third party payload.
|
||||
*
|
||||
* Outputs: A-> g_symbol_table, g_symbol_code,
|
||||
* g_lat, g_lon,
|
||||
|
@ -156,11 +157,10 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen);
|
|||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, int third_party)
|
||||
void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_src)
|
||||
{
|
||||
//dw_printf ("DEBUG decode_aprs quiet=%d, third_party=%d\n", quiet, third_party);
|
||||
//dw_printf ("DEBUG decode_aprs quiet=%d, third_party=%p\n", quiet, third_party_src);
|
||||
|
||||
//char dest[AX25_MAX_ADDR_LEN];
|
||||
unsigned char *pinfo;
|
||||
int info_len;
|
||||
|
||||
|
@ -229,7 +229,12 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, int third_party)
|
|||
|
||||
packet_t pp_payload = ax25_from_text ((char*)pinfo+1, 0);
|
||||
if (pp_payload != NULL) {
|
||||
decode_aprs (A, pp_payload, quiet, 1); // 1 means used recursively
|
||||
char payload_src[AX25_MAX_ADDR_LEN];
|
||||
memset(payload_src, 0, sizeof(payload_src));
|
||||
memcpy(payload_src, (char*)pinfo+1, sizeof(payload_src)-1);
|
||||
char *q = strchr(payload_src, '>');
|
||||
if (q != NULL) *q = '\0';
|
||||
decode_aprs (A, pp_payload, quiet, payload_src); // 1 means used recursively
|
||||
ax25_delete (pp_payload);
|
||||
return;
|
||||
}
|
||||
|
@ -243,8 +248,12 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, int third_party)
|
|||
/*
|
||||
* Extract source and destination including the SSID.
|
||||
*/
|
||||
|
||||
if (third_party_src != NULL) {
|
||||
strlcpy (A->g_src, third_party_src, sizeof(A->g_src));
|
||||
}
|
||||
else {
|
||||
ax25_get_addr_with_ssid (pp, AX25_SOURCE, A->g_src);
|
||||
}
|
||||
ax25_get_addr_with_ssid (pp, AX25_DESTINATION, A->g_dest);
|
||||
|
||||
//dw_printf ("DEBUG decode_aprs source=%s, dest=%s\n", A->g_src, A->g_dest);
|
||||
|
@ -5176,7 +5185,7 @@ int main (int argc, char *argv[])
|
|||
ax25_safe_print ((char *)pinfo, info_len, 1); // Display non-ASCII to hexadecimal.
|
||||
dw_printf ("\n");
|
||||
|
||||
decode_aprs (&A, pp, 0, 0); // Extract information into structure.
|
||||
decode_aprs (&A, pp, 0, NULL); // Extract information into structure.
|
||||
|
||||
decode_aprs_print (&A); // Now print it in human readable format.
|
||||
|
||||
|
@ -5197,7 +5206,7 @@ int main (int argc, char *argv[])
|
|||
if (pp != NULL) {
|
||||
decode_aprs_t A;
|
||||
|
||||
decode_aprs (&A, pp, 0, 0); // Extract information into structure.
|
||||
decode_aprs (&A, pp, 0, NULL); // Extract information into structure.
|
||||
|
||||
decode_aprs_print (&A); // Now print it in human readable format.
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ typedef struct decode_aprs_s {
|
|||
message_subtype_directed_query
|
||||
} g_message_subtype; /* Various cases of the overloaded "message." */
|
||||
|
||||
char g_message_number[8]; /* Message number. Should be 1 - 5 alphanumeric characters if used. */
|
||||
char g_message_number[12]; /* Message number. Should be 1 - 5 alphanumeric characters if used. */
|
||||
/* Addendum 1.1 has new format {mm} or {mm}aa with only two */
|
||||
/* characters for message number and an ack riding piggyback. */
|
||||
|
||||
|
@ -142,7 +142,7 @@ typedef struct decode_aprs_s {
|
|||
|
||||
|
||||
|
||||
extern void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, int third_party);
|
||||
extern void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_src);
|
||||
|
||||
extern void decode_aprs_print (decode_aprs_t *A);
|
||||
|
||||
|
|
|
@ -1426,7 +1426,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
// we still want to decode it for logging and other processing.
|
||||
// Just be quiet about errors if "-qd" is set.
|
||||
|
||||
decode_aprs (&A, pp, q_d_opt, 0);
|
||||
decode_aprs (&A, pp, q_d_opt, NULL);
|
||||
|
||||
if ( ! q_d_opt ) {
|
||||
|
||||
|
@ -1554,10 +1554,14 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
}
|
||||
else {
|
||||
|
||||
/* Send to Internet server if option is enabled. */
|
||||
/* Consider only those with correct CRC. */
|
||||
|
||||
if (ax25_is_aprs(pp) && retries == RETRY_NONE) {
|
||||
/*
|
||||
* Send to the IGate processing.
|
||||
* Use only those with correct CRC; We don't want to spread corrupted data!
|
||||
* Our earlier "fix bits" hack could allow corrupted information to get thru.
|
||||
* However, if it used FEC mode (FX.25. IL2P), we have much higher level of
|
||||
* confidence that it is correct.
|
||||
*/
|
||||
if (ax25_is_aprs(pp) && ( retries == RETRY_NONE || is_fx25) ) {
|
||||
|
||||
igate_send_rec_packet (chan, pp);
|
||||
}
|
||||
|
@ -1572,24 +1576,23 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
|
||||
|
||||
/*
|
||||
* APRS digipeater.
|
||||
* Send to APRS digipeater.
|
||||
* Use only those with correct CRC; We don't want to spread corrupted data!
|
||||
* Our earlier "fix bits" hack could allow corrupted information to get thru.
|
||||
* However, if it used FEC mode (FX.25. IL2P), we have much higher level of
|
||||
* confidence that it is correct.
|
||||
*/
|
||||
|
||||
// TODO: Should also use anything received with FX.25 because it is known to be good.
|
||||
// Our earlier "fix bits" hack could allow corrupted information to get thru.
|
||||
|
||||
if (ax25_is_aprs(pp) && retries == RETRY_NONE) {
|
||||
if (ax25_is_aprs(pp) && ( retries == RETRY_NONE || is_fx25) ) {
|
||||
|
||||
digipeater (chan, pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Connected mode digipeater.
|
||||
* Use only those with correct CRC.
|
||||
* Use only those with correct CRC (or using FEC.)
|
||||
*/
|
||||
|
||||
if (retries == RETRY_NONE) {
|
||||
if (retries == RETRY_NONE || is_fx25) {
|
||||
|
||||
cdigipeater (chan, pp);
|
||||
}
|
||||
|
|
127
src/igate.c
127
src/igate.c
|
@ -203,6 +203,8 @@ static char * ia_to_text (int Family, void * pAddr, char * pStringBuf, size_t S
|
|||
|
||||
#if ITEST
|
||||
|
||||
// TODO: Add to automated tests.
|
||||
|
||||
/* For unit testing. */
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
|
@ -1713,7 +1715,14 @@ static void * satgate_delay_thread (void *arg)
|
|||
* K1RI-2>APWW10,WIDE1-1,WIDE2-1,qAS,K1RI:/221700h/9AmA<Ct3_ sT010/002g005t045r000p023P020h97b10148
|
||||
* KC1BOS-2>T3PQ3S,WIDE1-1,WIDE2-1,qAR,W1TG-1:`c)@qh\>/"50}TinyTrak4 Mobile
|
||||
*
|
||||
* Notice how the final address in the header might not
|
||||
* This is interesting because the source is not a valid AX.25 address.
|
||||
* Non-RF stations can have 2 alphanumeric characters for SSID.
|
||||
* In this example, the WHO-IS server is responding to a message.
|
||||
*
|
||||
* WHO-IS>APJIW4,TCPIP*,qAC,AE5PL-JF::ZL1JSH-9 :Charles Beadfield/New Zealand{583
|
||||
*
|
||||
*
|
||||
* Notice how the final digipeater address, in the header, might not
|
||||
* be a valid AX.25 address. We see a 9 character address
|
||||
* (with no ssid) and an ssid of two letters.
|
||||
* We don't care because we end up discarding them before
|
||||
|
@ -1728,29 +1737,37 @@ static void * satgate_delay_thread (void *arg)
|
|||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
// TODO: Use of "message" here is confusing because that term already
|
||||
// has a special meaning for APRS. This could be an APRS message or
|
||||
// some other APRS data type. Payload is already used.
|
||||
|
||||
static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
||||
{
|
||||
packet_t pp3;
|
||||
char payload[AX25_MAX_PACKET_LEN]; /* what is max len? */
|
||||
char src[AX25_MAX_ADDR_LEN]; /* Source address. */
|
||||
|
||||
char *pinfo = NULL;
|
||||
int info_len;
|
||||
int n;
|
||||
|
||||
assert (to_chan >= 0 && to_chan < MAX_CHANS);
|
||||
|
||||
|
||||
/*
|
||||
* Try to parse it into a packet object.
|
||||
* This will contain "q constructs" and we might see an address
|
||||
* with two alphnumeric characters in the SSID so we must use
|
||||
* the non-strict parsing.
|
||||
* Try to parse it into a packet object; we need this for the packet filtering.
|
||||
*
|
||||
* Bug: Up to 8 digipeaters are allowed in radio format.
|
||||
* There is a potential of finding a larger number here.
|
||||
* We use the non-strict option because there the via path can have:
|
||||
* - station names longer than 6.
|
||||
* - alphanumeric SSID.
|
||||
* - lower case for "q constructs.
|
||||
* We don't care about any of those because the via path will be discarded anyhow.
|
||||
*
|
||||
* The other issue, that I did not think of originally, is that the "source"
|
||||
* address might not conform to AX.25 restrictions when it originally came
|
||||
* from a non-RF source. For example an APRS "message" might be sent to the
|
||||
* "WHO-IS" server, and the reply message would have that for the source address.
|
||||
*
|
||||
* Originally, I used the source address from the packet object but that was
|
||||
* missing the alphanumeric SSID. This needs to be done differently.
|
||||
*
|
||||
* Potential Bug: Up to 8 digipeaters are allowed in radio format.
|
||||
* Is there a possibility of finding a larger number here?
|
||||
*/
|
||||
pp3 = ax25_from_text(message, 0);
|
||||
packet_t pp3 = ax25_from_text(message, 0);
|
||||
if (pp3 == NULL) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Tx IGate: Could not parse message from server.\n");
|
||||
|
@ -1758,7 +1775,21 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
|||
return;
|
||||
}
|
||||
|
||||
ax25_get_addr_with_ssid (pp3, AX25_SOURCE, src);
|
||||
// Issue 408: The source address might not be valid AX.25 because it
|
||||
// came from a non-RF station. e.g. some server responding to a message.
|
||||
// We need to take source address from original rather than extracting it
|
||||
// from the packet object.
|
||||
|
||||
char src[AX25_MAX_ADDR_LEN]; /* Source address. */
|
||||
memset (src, 0, sizeof(src));
|
||||
memcpy (src, message, sizeof(src)-1);
|
||||
char *gt = strchr(src, '>');
|
||||
if (gt != NULL) {
|
||||
*gt = '\0';
|
||||
}
|
||||
|
||||
// FIXME NO!
|
||||
///////ax25_get_addr_with_ssid (pp3, AX25_SOURCE, src);
|
||||
|
||||
/*
|
||||
* Drop if path contains:
|
||||
|
@ -1770,8 +1801,8 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
|||
|
||||
ax25_get_addr_with_ssid (pp3, n + AX25_REPEATER_1, via);
|
||||
|
||||
if (strcmp(via, "qAX") == 0 ||
|
||||
strcmp(via, "TCPXX") == 0 ||
|
||||
if (strcmp(via, "qAX") == 0 || // qAX deprecated. http://www.aprs-is.net/q.aspx
|
||||
strcmp(via, "TCPXX") == 0 || // TCPXX deprecated.
|
||||
strcmp(via, "RFONLY") == 0 ||
|
||||
strcmp(via, "NOGATE") == 0) {
|
||||
|
||||
|
@ -1807,7 +1838,8 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
|||
// TODO: Not quite this simple. Should have a function to check for position.
|
||||
// $ raw gps could be a position. @ could be weather data depending on symbol.
|
||||
|
||||
info_len = ax25_get_info (pp3, (unsigned char **)(&pinfo));
|
||||
char *pinfo = NULL;
|
||||
int info_len = ax25_get_info (pp3, (unsigned char **)(&pinfo));
|
||||
|
||||
int msp_special_case = 0;
|
||||
|
||||
|
@ -1837,12 +1869,6 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
|||
// Previously there was a debug message here about the packet being dropped by filtering.
|
||||
// This is now handled better by the "-df" command line option for filtering details.
|
||||
|
||||
// TODO: clean up - remove these lines.
|
||||
//if (s_debug >= 1) {
|
||||
// text_color_set(DW_COLOR_INFO);
|
||||
// dw_printf ("Packet from IGate to channel %d was rejected by filter: %s\n", to_chan, save_digi_config_p->filter_str[MAX_CHANS][to_chan]);
|
||||
//}
|
||||
|
||||
ax25_delete (pp3);
|
||||
return;
|
||||
}
|
||||
|
@ -1851,13 +1877,15 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
|||
|
||||
|
||||
/*
|
||||
* Remove the VIA path.
|
||||
* We want to discard the via path, as received from the APRS-IS, then
|
||||
* replace it with TCPIP and our own call, marked as used.
|
||||
*
|
||||
*
|
||||
* For example, we might get something like this from the server.
|
||||
* K1USN-1>APWW10,TCPIP*,qAC,N5JXS-F1:T#479,100,048,002,500,000,10000000<0x0d><0x0a>
|
||||
* K1USN-1>APWW10,TCPIP*,qAC,N5JXS-F1:T#479,100,048,002,500,000,10000000
|
||||
*
|
||||
* We want to reduce it to this before wrapping it as third party traffic.
|
||||
* K1USN-1>APWW10:T#479,100,048,002,500,000,10000000<0x0d><0x0a>
|
||||
* We want to transform it to this before wrapping it as third party traffic.
|
||||
* K1USN-1>APWW10,TCPIP,mycall*:T#479,100,048,002,500,000,10000000
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -1885,37 +1913,24 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
|||
*
|
||||
* What is the ",I" construct?
|
||||
* Do we care here?
|
||||
* Is is something new and improved that we should be using in the other direction?
|
||||
* Is it something new and improved that we should be using in the other direction?
|
||||
*/
|
||||
|
||||
while (ax25_get_num_repeaters(pp3) > 0) {
|
||||
ax25_remove_addr (pp3, AX25_REPEATER_1);
|
||||
}
|
||||
char payload[AX25_MAX_PACKET_LEN];
|
||||
|
||||
char dest[AX25_MAX_ADDR_LEN]; /* Destination field. */
|
||||
ax25_get_addr_with_ssid (pp3, AX25_DESTINATION, dest);
|
||||
snprintf (payload, sizeof(payload), "%s>%s,TCPIP,%s*:%s",
|
||||
src, dest, save_audio_config_p->achan[to_chan].mycall, pinfo);
|
||||
|
||||
|
||||
/*
|
||||
* Replace the VIA path with TCPIP and my call.
|
||||
* Mark my call as having been used.
|
||||
*/
|
||||
ax25_set_addr (pp3, AX25_REPEATER_1, "TCPIP");
|
||||
ax25_set_h (pp3, AX25_REPEATER_1);
|
||||
ax25_set_addr (pp3, AX25_REPEATER_2, save_audio_config_p->achan[to_chan].mycall);
|
||||
ax25_set_h (pp3, AX25_REPEATER_2);
|
||||
|
||||
/*
|
||||
* Convert to text representation.
|
||||
*/
|
||||
memset (payload, 0, sizeof(payload));
|
||||
|
||||
ax25_format_addrs (pp3, payload);
|
||||
info_len = ax25_get_info (pp3, (unsigned char **)(&pinfo));
|
||||
(void)(info_len);
|
||||
strlcat (payload, pinfo, sizeof(payload));
|
||||
#if DEBUGx
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("Tx IGate: payload=%s\n", payload);
|
||||
dw_printf ("Tx IGate: DEBUG payload=%s\n", payload);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Encapsulate for sending over radio if no reason to drop it.
|
||||
*/
|
||||
|
@ -1931,19 +1946,13 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
|||
*/
|
||||
if (ig_to_tx_allow (pp3, to_chan)) {
|
||||
char radio [2400];
|
||||
packet_t pradio;
|
||||
|
||||
snprintf (radio, sizeof(radio), "%s>%s%d%d%s:}%s",
|
||||
save_audio_config_p->achan[to_chan].mycall,
|
||||
APP_TOCALL, MAJOR_VERSION, MINOR_VERSION,
|
||||
save_igate_config_p->tx_via,
|
||||
payload);
|
||||
|
||||
pradio = ax25_from_text (radio, 1);
|
||||
|
||||
/* Oops. Didn't have a check for NULL here. */
|
||||
/* Could this be the cause of rare and elusive crashes in 1.2? */
|
||||
|
||||
packet_t pradio = ax25_from_text (radio, 1);
|
||||
if (pradio != NULL) {
|
||||
|
||||
#if ITEST
|
||||
|
|
|
@ -84,6 +84,8 @@ struct kissport_status_s {
|
|||
// The default is a limit of 3 client applications at the same time.
|
||||
// You can increase the limit by changing the line below.
|
||||
// A larger number consumes more resources so don't go crazy by making it larger than needed.
|
||||
// TODO: Should this be moved to direwolf.h so max number of audio devices
|
||||
// client apps are in the same place?
|
||||
|
||||
#define MAX_NET_CLIENTS 3
|
||||
|
||||
|
|
|
@ -67,9 +67,7 @@
|
|||
#include "serial_port.h"
|
||||
#include "kiss_frame.h"
|
||||
#include "dwsock.h"
|
||||
#include "dtime_now.h"
|
||||
#include "audio.h" // for DEFAULT_TXDELAY, etc.
|
||||
#include "dtime_now.h"
|
||||
|
||||
|
||||
// TODO: define in one place, use everywhere.
|
||||
|
|
36
src/mheard.c
36
src/mheard.c
|
@ -434,6 +434,7 @@ void mheard_save_rf (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, r
|
|||
* N1HKO-10>APJI40,TCPIP*,qAC,N1HKO-JS:<IGATE,MSG_CNT=0,LOC_CNT=0
|
||||
* K1RI-2>APWW10,WIDE1-1,WIDE2-1,qAS,K1RI:/221700h/9AmA<Ct3_ sT010/002g005t045r000p023P020h97b10148
|
||||
* KC1BOS-2>T3PQ3S,WIDE1-1,WIDE2-1,qAR,W1TG-1:`c)@qh\>/"50}TinyTrak4 Mobile
|
||||
* WHO-IS>APJIW4,TCPIP*,qAC,AE5PL-JF::WB2OSZ :C/Billerica Amateur Radio Society/MA/United States{XF}WO
|
||||
*
|
||||
* Notice how the final address in the header might not
|
||||
* be a valid AX.25 address. We see a 9 character address
|
||||
|
@ -443,6 +444,7 @@ void mheard_save_rf (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, r
|
|||
* a clue about the journey taken but I don't think we care here.
|
||||
*
|
||||
* All we should care about here is the the source address.
|
||||
* Note that the source address might not adhere to the AX.25 format.
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
|
@ -450,21 +452,25 @@ void mheard_save_rf (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, r
|
|||
|
||||
void mheard_save_is (char *ptext)
|
||||
{
|
||||
packet_t pp;
|
||||
time_t now = time(NULL);
|
||||
char source[AX25_MAX_ADDR_LEN];
|
||||
mheard_t *mptr;
|
||||
|
||||
#if 1
|
||||
// It is possible that source won't adhere to the AX.25 restrictions.
|
||||
// So we simply extract the source address, as text, from the beginning rather than
|
||||
// using ax25_from_text() and ax25_get_addr_with_ssid().
|
||||
|
||||
memset (source, 0, sizeof(source));
|
||||
memcpy (source, ptext, sizeof(source)-1);
|
||||
char *g = strchr(source, '>');
|
||||
if (g != NULL) *g = '\0';
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Try to parse it into a packet object.
|
||||
* This will contain "q constructs" and we might see an address
|
||||
* with two alphnumeric characters in the SSID so we must use
|
||||
* the non-strict parsing.
|
||||
*
|
||||
* Bug: Up to 8 digipeaters are allowed in radio format.
|
||||
* There is a potential of finding a larger number here.
|
||||
* Keep this here in case I want to revive it to get location.
|
||||
*/
|
||||
pp = ax25_from_text(ptext, 0);
|
||||
packet_t pp = ax25_from_text(ptext, 0);
|
||||
|
||||
if (pp == NULL) {
|
||||
if (mheard_debug) {
|
||||
|
@ -475,13 +481,17 @@ void mheard_save_is (char *ptext)
|
|||
return;
|
||||
}
|
||||
|
||||
ax25_get_addr_with_ssid (pp, AX25_SOURCE, source);
|
||||
//////ax25_get_addr_with_ssid (pp, AX25_SOURCE, source);
|
||||
#endif
|
||||
|
||||
mptr = mheard_ptr(source);
|
||||
mheard_t *mptr = mheard_ptr(source);
|
||||
if (mptr == NULL) {
|
||||
int i;
|
||||
/*
|
||||
* Not heard before. Add it.
|
||||
* Observation years later:
|
||||
* Hmmmm. I wonder why I did not store the location if available.
|
||||
* An earlier example has an APRSdroid station reporting location without using [ham] RF.
|
||||
*/
|
||||
|
||||
if (mheard_debug) {
|
||||
|
@ -537,7 +547,9 @@ void mheard_save_is (char *ptext)
|
|||
mheard_dump ();
|
||||
}
|
||||
|
||||
#if 0
|
||||
ax25_delete (pp);
|
||||
#endif
|
||||
|
||||
} /* end mheard_save_is */
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ int pfilter (int from_chan, int to_chan, char *filter, packet_t pp, int is_aprs)
|
|||
pfstate.is_aprs = is_aprs;
|
||||
|
||||
if (is_aprs) {
|
||||
decode_aprs (&pfstate.decoded, pp, 1, 0);
|
||||
decode_aprs (&pfstate.decoded, pp, 1, NULL);
|
||||
}
|
||||
|
||||
next_token(&pfstate);
|
||||
|
@ -1278,7 +1278,8 @@ static int filt_s (pfstate_t *pf)
|
|||
*
|
||||
* Name: filt_i
|
||||
*
|
||||
* Purpose: IGate messaging default behavior.
|
||||
* Purpose: IGate messaging filter.
|
||||
* This would make sense only for IS>RF direction.
|
||||
*
|
||||
* Inputs: pf - Pointer to current state information.
|
||||
* token_str should contain something of format:
|
||||
|
@ -1307,7 +1308,7 @@ static int filt_s (pfstate_t *pf)
|
|||
* The rest is distanced, in kilometers, from given point.
|
||||
*
|
||||
* Examples:
|
||||
* i/60/0 Heard in past 60 minutes directly.
|
||||
* i/180/0 Heard in past 3 hours directly.
|
||||
* i/45 Past 45 minutes, default max digi hops.
|
||||
* i/180/3 Default time (3 hours), max 3 digi hops.
|
||||
* i/180/8/42.6/-71.3/50.
|
||||
|
@ -1317,13 +1318,17 @@ static int filt_s (pfstate_t *pf)
|
|||
* The basic idea is that we want to transmit a "message" only if the
|
||||
* addressee has been heard recently and is not too far away.
|
||||
*
|
||||
* That is so we can distinguish messages addressed to a specific
|
||||
* station, and other sundry uses of the addressee field.
|
||||
*
|
||||
* After passing along a "message" we will also allow the next
|
||||
* position report from the sender of the "message."
|
||||
* That is done somewhere else. We are not concerned with it here.
|
||||
*
|
||||
* IMHO, the rules here are too restrictive.
|
||||
*
|
||||
* FIXME -explain
|
||||
* (1) The APRS-IS would send a "message" to my IGate only if the addressee
|
||||
* has been heard nearby recently. 180 minutes, I believe.
|
||||
*
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
|
|
10
src/ptt.c
10
src/ptt.c
|
@ -357,6 +357,9 @@ static void get_access_to_gpio (const char *path)
|
|||
* We don't have permission.
|
||||
* Try a hack which requires that the user be set up to use sudo without a password.
|
||||
*/
|
||||
// FIXME: I think this was a horrible work around for some early release that
|
||||
// did not give gpio permission to the pi user. This should go.
|
||||
// Provide recovery instructions when there is a permission failure.
|
||||
|
||||
if (ptt_debug_level >= 2) {
|
||||
text_color_set(DW_COLOR_ERROR); // debug message but different color so it stands out.
|
||||
|
@ -494,6 +497,13 @@ void export_gpio(int ch, int ot, int invert, int direction)
|
|||
* matching the pattern "gpio61_*".
|
||||
*
|
||||
* We are finally implementing the third choice.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Then we have the Odroid board with GPIO numbers starting around 480.
|
||||
* Can we simply use those numbers?
|
||||
* Apparently, the export names look like GPIOX.17
|
||||
* https://wiki.odroid.com/odroid-c4/hardware/expansion_connectors#gpio_map_for_wiringpi_library
|
||||
*/
|
||||
|
||||
struct dirent **file_list;
|
||||
|
|
|
@ -107,7 +107,6 @@
|
|||
#include "recv.h"
|
||||
#include "dtmf.h"
|
||||
#include "aprs_tt.h"
|
||||
#include "dtime_now.h"
|
||||
#include "ax25_link.h"
|
||||
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@
|
|||
* You can increase the limit by changing the line below.
|
||||
* A larger number consumes more resources so don't go crazy by making it larger than needed.
|
||||
*/
|
||||
// FIXME: Put in direwolf.h rather than in .c file. Change name to reflect AGW vs KISS. Update user guide 5.7.
|
||||
|
||||
#define MAX_NET_CLIENTS 3
|
||||
|
||||
|
|
Loading…
Reference in New Issue