mirror of https://github.com/wb2osz/direwolf.git
New "-d d" command line option for APRStt debug.
This commit is contained in:
parent
791982a5e4
commit
fdf660a7f1
|
@ -122,6 +122,8 @@ m = Monitor heard station list.
|
||||||
f = Packet filtering.
|
f = Packet filtering.
|
||||||
.P
|
.P
|
||||||
x = FX.25 increase verbose level.
|
x = FX.25 increase verbose level.
|
||||||
|
.P
|
||||||
|
d = APRStt (DTMF to APRS object conversion).
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
.PD
|
.PD
|
||||||
|
|
113
src/aprs_tt.c
113
src/aprs_tt.c
|
@ -115,6 +115,8 @@ static int find_ttloc_match (char *e, char *xstr, char *ystr, char *zstr, char *
|
||||||
static void check_result (void);
|
static void check_result (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int tt_debug = 0;
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------
|
/*------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
@ -122,7 +124,8 @@ static void check_result (void);
|
||||||
*
|
*
|
||||||
* Purpose: Initialize the APRStt gateway at system startup time.
|
* Purpose: Initialize the APRStt gateway at system startup time.
|
||||||
*
|
*
|
||||||
* Inputs: Configuration options gathered by config.c.
|
* Inputs: P - Pointer to configuration options gathered by config.c.
|
||||||
|
* debug - Debug printing control.
|
||||||
*
|
*
|
||||||
* Global out: Make our own local copy of the structure here.
|
* Global out: Make our own local copy of the structure here.
|
||||||
*
|
*
|
||||||
|
@ -164,9 +167,10 @@ static struct ttloc_s test_config[] = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void aprs_tt_init (struct tt_config_s *p)
|
void aprs_tt_init (struct tt_config_s *p, int debug)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
tt_debug = debug;
|
||||||
|
|
||||||
#if TT_MAIN
|
#if TT_MAIN
|
||||||
/* For unit testing. */
|
/* For unit testing. */
|
||||||
|
@ -483,7 +487,19 @@ static int parse_fields (char *msg)
|
||||||
//text_color_set(DW_COLOR_DEBUG);
|
//text_color_set(DW_COLOR_DEBUG);
|
||||||
//dw_printf ("parse_fields (%s).\n", msg);
|
//dw_printf ("parse_fields (%s).\n", msg);
|
||||||
|
|
||||||
strlcpy (stemp, msg, sizeof(stemp));
|
// Make a copy of msg because strtok corrupts the original.
|
||||||
|
// While we are at it, remove any blanks.
|
||||||
|
// This should not happen with DTMF reception but could happen
|
||||||
|
// in manually crafted strings for testing.
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
for (char *m = msg; *m != '\0' && n < sizeof(stemp)-1; m++) {
|
||||||
|
if (*m != ' ') {
|
||||||
|
stemp[n++] = *m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stemp[n] = '\0';
|
||||||
|
|
||||||
e = strtok_r (stemp, "*#", &save);
|
e = strtok_r (stemp, "*#", &save);
|
||||||
while (e != NULL) {
|
while (e != NULL) {
|
||||||
|
|
||||||
|
@ -551,7 +567,7 @@ static int parse_fields (char *msg)
|
||||||
default:
|
default:
|
||||||
|
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Field does not start with A, B, C, or digit: \"%s\"\n", msg);
|
dw_printf ("Field does not start with A, B, C, or digit: \"%s\"\n", e);
|
||||||
return (TT_ERROR_D_MSG);
|
return (TT_ERROR_D_MSG);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -690,17 +706,15 @@ static int expand_macro (char *e)
|
||||||
*
|
*
|
||||||
* Inputs: e - An "entry" extracted from a complete
|
* Inputs: e - An "entry" extracted from a complete
|
||||||
* APRStt messsage.
|
* APRStt messsage.
|
||||||
* In this case, it should start with "A".
|
* In this case, it should start with "A" then a digit.
|
||||||
*
|
*
|
||||||
* Outputs: m_callsign
|
* Outputs: m_callsign
|
||||||
*
|
*
|
||||||
* m_symtab_or_overlay - Set to 0-9 or A-Z if specified.
|
* m_symtab_or_overlay - Set to 0-9 or A-Z if specified.
|
||||||
*
|
*
|
||||||
* m_symbol_code - Always set to 'A'.
|
* m_symbol_code - Always set to 'A' (Box, DTMF or RFID)
|
||||||
* NO! This should be applied only if we
|
* If you want a different symbol, use the new
|
||||||
* have the default value at this point.
|
* object name format and separate symbol specification.
|
||||||
* The symbol might have been explicitly
|
|
||||||
* set already and we don't want to overwrite that.
|
|
||||||
*
|
*
|
||||||
* Returns: 0 for success or one of the TT_ERROR_... codes.
|
* Returns: 0 for success or one of the TT_ERROR_... codes.
|
||||||
*
|
*
|
||||||
|
@ -752,6 +766,11 @@ static int parse_callsign (char *e)
|
||||||
int len;
|
int len;
|
||||||
char tttemp[40], stemp[30];
|
char tttemp[40], stemp[30];
|
||||||
|
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("APRStt parse callsign (starts with A then digit): \"%s\"\n", e);
|
||||||
|
}
|
||||||
|
|
||||||
assert (*e == 'A');
|
assert (*e == 'A');
|
||||||
|
|
||||||
len = strlen(e);
|
len = strlen(e);
|
||||||
|
@ -762,6 +781,10 @@ static int parse_callsign (char *e)
|
||||||
|
|
||||||
if (len == 4 && isdigit(e[1]) && isdigit(e[2]) && isdigit(e[3])) {
|
if (len == 4 && isdigit(e[1]) && isdigit(e[2]) && isdigit(e[3])) {
|
||||||
strlcpy (m_callsign, e+1, sizeof(m_callsign));
|
strlcpy (m_callsign, e+1, sizeof(m_callsign));
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("Special case, 3 digit tactical call: \"%s\"\n", m_callsign);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,7 +802,7 @@ static int parse_callsign (char *e)
|
||||||
return (cs_err);
|
return (cs_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy (m_callsign, e+1, 3);
|
memcpy (m_callsign, e+1, 3);
|
||||||
m_callsign[3] = '\0';
|
m_callsign[3] = '\0';
|
||||||
|
|
||||||
if (len == 7) {
|
if (len == 7) {
|
||||||
|
@ -789,10 +812,20 @@ static int parse_callsign (char *e)
|
||||||
tt_two_key_to_text (tttemp, 0, stemp);
|
tt_two_key_to_text (tttemp, 0, stemp);
|
||||||
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
||||||
m_symtab_or_overlay = stemp[0];
|
m_symtab_or_overlay = stemp[0];
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("Three digit abbreviation1: callsign \"%s\", symbol code '%c (Box DTMF)', overlay '%c', checksum %c\n",
|
||||||
|
m_callsign, m_symbol_code, m_symtab_or_overlay, e[len-1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
||||||
m_symtab_or_overlay = e[len-2];
|
m_symtab_or_overlay = e[len-2];
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("Three digit abbreviation2: callsign \"%s\", symbol code '%c' (Box DTMF), overlay '%c', checksum %c\n",
|
||||||
|
m_callsign, m_symbol_code, m_symtab_or_overlay, e[len-1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -810,7 +843,7 @@ static int parse_callsign (char *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isupper(e[len-2])) {
|
if (isupper(e[len-2])) {
|
||||||
strncpy (tttemp, e+1, len-4);
|
memcpy (tttemp, e+1, len-4);
|
||||||
tttemp[len-4] = '\0';
|
tttemp[len-4] = '\0';
|
||||||
tt_two_key_to_text (tttemp, 0, m_callsign);
|
tt_two_key_to_text (tttemp, 0, m_callsign);
|
||||||
|
|
||||||
|
@ -820,14 +853,24 @@ static int parse_callsign (char *e)
|
||||||
tt_two_key_to_text (tttemp, 0, stemp);
|
tt_two_key_to_text (tttemp, 0, stemp);
|
||||||
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
||||||
m_symtab_or_overlay = stemp[0];
|
m_symtab_or_overlay = stemp[0];
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("Callsign in two key format1: callsign \"%s\", symbol code '%c' (Box DTMF), overlay '%c', checksum %c\n",
|
||||||
|
m_callsign, m_symbol_code, m_symtab_or_overlay, e[len-1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strncpy (tttemp, e+1, len-3);
|
memcpy (tttemp, e+1, len-3);
|
||||||
tttemp[len-3] = '\0';
|
tttemp[len-3] = '\0';
|
||||||
tt_two_key_to_text (tttemp, 0, m_callsign);
|
tt_two_key_to_text (tttemp, 0, m_callsign);
|
||||||
|
|
||||||
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
m_symbol_code = APRSTT_DEFAULT_SYMBOL;
|
||||||
m_symtab_or_overlay = e[len-2];
|
m_symtab_or_overlay = e[len-2];
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("Callsign in two key format2: callsign \"%s\", symbol code '%c' (Box DTMF), overlay '%c', checksum %c\n",
|
||||||
|
m_callsign, m_symbol_code, m_symtab_or_overlay, e[len-1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -864,9 +907,11 @@ static int parse_callsign (char *e)
|
||||||
static int parse_object_name (char *e)
|
static int parse_object_name (char *e)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
//int c_length;
|
|
||||||
//char tttemp[40];
|
if (tt_debug) {
|
||||||
//char stemp[30];
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("APRStt parse object name (starts with AA): \"%s\"\n", e);
|
||||||
|
}
|
||||||
|
|
||||||
assert (e[0] == 'A');
|
assert (e[0] == 'A');
|
||||||
assert (e[1] == 'A');
|
assert (e[1] == 'A');
|
||||||
|
@ -882,6 +927,10 @@ static int parse_object_name (char *e)
|
||||||
if (tt_two_key_to_text (e+2, 0, m_callsign) == 0) {
|
if (tt_two_key_to_text (e+2, 0, m_callsign) == 0) {
|
||||||
m_callsign[9] = '\0'; /* truncate to 9 */
|
m_callsign[9] = '\0'; /* truncate to 9 */
|
||||||
m_ssid = 0; /* No ssid for object name */
|
m_ssid = 0; /* No ssid for object name */
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("Object name in two key format: \"%s\"\n", m_callsign);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -935,6 +984,11 @@ static int parse_symbol (char *e)
|
||||||
int nn;
|
int nn;
|
||||||
char stemp[10];
|
char stemp[10];
|
||||||
|
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("APRStt parse symbol (starts with AB): \"%s\"\n", e);
|
||||||
|
}
|
||||||
|
|
||||||
assert (e[0] == 'A');
|
assert (e[0] == 'A');
|
||||||
assert (e[1] == 'B');
|
assert (e[1] == 'B');
|
||||||
|
|
||||||
|
@ -959,12 +1013,22 @@ static int parse_symbol (char *e)
|
||||||
case '1':
|
case '1':
|
||||||
m_symtab_or_overlay = '/';
|
m_symtab_or_overlay = '/';
|
||||||
m_symbol_code = 32 + nn;
|
m_symbol_code = 32 + nn;
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("symbol code '%c', primary symbol table '%c'\n",
|
||||||
|
m_symbol_code, m_symtab_or_overlay);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '2':
|
case '2':
|
||||||
m_symtab_or_overlay = '\\';
|
m_symtab_or_overlay = '\\';
|
||||||
m_symbol_code = 32 + nn;
|
m_symbol_code = 32 + nn;
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("symbol code '%c', alternate symbol table '%c'\n",
|
||||||
|
m_symbol_code, m_symtab_or_overlay);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -973,6 +1037,11 @@ static int parse_symbol (char *e)
|
||||||
if (tt_two_key_to_text (e+5, 0, stemp) == 0) {
|
if (tt_two_key_to_text (e+5, 0, stemp) == 0) {
|
||||||
m_symbol_code = 32 + nn;
|
m_symbol_code = 32 + nn;
|
||||||
m_symtab_or_overlay = stemp[0];
|
m_symtab_or_overlay = stemp[0];
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("symbol code '%c', alternate symbol table with overlay '%c'\n",
|
||||||
|
m_symbol_code, m_symtab_or_overlay);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1018,6 +1087,11 @@ static int parse_aprstt3_call (char *e)
|
||||||
assert (e[0] == 'A');
|
assert (e[0] == 'A');
|
||||||
assert (e[1] == 'C');
|
assert (e[1] == 'C');
|
||||||
|
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("APRStt parse QIKcom-2 / APRStt 3 ten digit call or five digit suffix (starts with AC): \"%s\"\n", e);
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen(e) == 2+10) {
|
if (strlen(e) == 2+10) {
|
||||||
char call[12];
|
char call[12];
|
||||||
|
|
||||||
|
@ -1125,6 +1199,11 @@ static int parse_location (char *e)
|
||||||
char mh[20];
|
char mh[20];
|
||||||
char stemp[32];
|
char stemp[32];
|
||||||
|
|
||||||
|
if (tt_debug) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("APRStt parse location (starts with B): \"%s\"\n", e);
|
||||||
|
// TODO: more detail later...
|
||||||
|
}
|
||||||
|
|
||||||
assert (*e == 'B');
|
assert (*e == 'B');
|
||||||
|
|
||||||
|
@ -1985,7 +2064,7 @@ static void check_result (void)
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
aprs_tt_init (NULL);
|
aprs_tt_init (NULL, 0);
|
||||||
|
|
||||||
error_count = 0;
|
error_count = 0;
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ struct tt_config_s {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void aprs_tt_init (struct tt_config_s *p_config);
|
void aprs_tt_init (struct tt_config_s *p_config, int debug);
|
||||||
|
|
||||||
void aprs_tt_button (int chan, char button);
|
void aprs_tt_button (int chan, char button);
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,7 @@ int main (int argc, char *argv[])
|
||||||
int d_h_opt = 0; /* "-d h" option for hamlib debugging. Repeat for more detail */
|
int d_h_opt = 0; /* "-d h" option for hamlib debugging. Repeat for more detail */
|
||||||
#endif
|
#endif
|
||||||
int d_x_opt = 1; /* "-d x" option for FX.25. Default minimal. Repeat for more detail. -qx to silence. */
|
int d_x_opt = 1; /* "-d x" option for FX.25. Default minimal. Repeat for more detail. -qx to silence. */
|
||||||
|
int aprstt_debug = 0; /* "-d d" option for APRStt (think Dtmf) debug. */
|
||||||
|
|
||||||
int E_tx_opt = 0; /* "-E n" Error rate % for clobbering trasmit frames. */
|
int E_tx_opt = 0; /* "-E n" Error rate % for clobbering trasmit frames. */
|
||||||
int E_rx_opt = 0; /* "-E Rn" Error rate % for clobbering receive frames. */
|
int E_rx_opt = 0; /* "-E Rn" Error rate % for clobbering receive frames. */
|
||||||
|
@ -566,6 +567,7 @@ int main (int argc, char *argv[])
|
||||||
case 'h': d_h_opt++; break; // Hamlib verbose level.
|
case 'h': d_h_opt++; break; // Hamlib verbose level.
|
||||||
#endif
|
#endif
|
||||||
case 'x': d_x_opt++; break; // FX.25
|
case 'x': d_x_opt++; break; // FX.25
|
||||||
|
case 'd': aprstt_debug++; break; // APRStt (mnemonic Dtmf)
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,7 +760,7 @@ int main (int argc, char *argv[])
|
||||||
// Will make more precise in afsk demod init.
|
// Will make more precise in afsk demod init.
|
||||||
audio_config.achan[0].mark_freq = 2083; // Actually 2083.3 - logic 1.
|
audio_config.achan[0].mark_freq = 2083; // Actually 2083.3 - logic 1.
|
||||||
audio_config.achan[0].space_freq = 1563; // Actually 1562.5 - logic 0.
|
audio_config.achan[0].space_freq = 1563; // Actually 1562.5 - logic 0.
|
||||||
strlcpy (audio_config.achan[0].profiles, "D", sizeof(audio_config.achan[0].profiles));
|
strlcpy (audio_config.achan[0].profiles, "A", sizeof(audio_config.achan[0].profiles));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
audio_config.achan[0].modem_type = MODEM_SCRAMBLE;
|
audio_config.achan[0].modem_type = MODEM_SCRAMBLE;
|
||||||
|
@ -883,7 +885,7 @@ int main (int argc, char *argv[])
|
||||||
* Initialize the touch tone decoder & APRStt gateway.
|
* Initialize the touch tone decoder & APRStt gateway.
|
||||||
*/
|
*/
|
||||||
dtmf_init (&audio_config, audio_amplitude);
|
dtmf_init (&audio_config, audio_amplitude);
|
||||||
aprs_tt_init (&tt_config);
|
aprs_tt_init (&tt_config, aprstt_debug);
|
||||||
tt_user_init (&audio_config, &tt_config);
|
tt_user_init (&audio_config, &tt_config);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1345,18 +1347,24 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it came from DTMF decoder, send it to APRStt gateway.
|
* If it came from DTMF decoder (subchan == -1), send it to APRStt gateway.
|
||||||
* Otherwise, it is a candidate for IGate and digipeater.
|
* Otherwise, it is a candidate for IGate and digipeater.
|
||||||
*
|
*
|
||||||
* TODO: It would be useful to have some way to simulate touch tone
|
* It is also useful to have some way to simulate touch tone
|
||||||
* sequences with BEACON sendto=R0 for testing.
|
* sequences with BEACON sendto=R0 for testing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (subchan == -1) {
|
if (subchan == -1) { // from DTMF decoder
|
||||||
if (tt_config.gateway_enabled && info_len >= 2) {
|
if (tt_config.gateway_enabled && info_len >= 2) {
|
||||||
aprs_tt_sequence (chan, (char*)(pinfo+1));
|
aprs_tt_sequence (chan, (char*)(pinfo+1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (*pinfo == 't' && info_len >= 2 && tt_config.gateway_enabled) {
|
||||||
|
// For testing.
|
||||||
|
// Would be nice to verify it was generated locally,
|
||||||
|
// not received over the air.
|
||||||
|
aprs_tt_sequence (chan, (char*)(pinfo+1));
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
/* Send to Internet server if option is enabled. */
|
/* Send to Internet server if option is enabled. */
|
||||||
|
@ -1487,6 +1495,7 @@ static void usage (char **argv)
|
||||||
dw_printf (" h h = hamlib increase verbose level.\n");
|
dw_printf (" h h = hamlib increase verbose level.\n");
|
||||||
#endif
|
#endif
|
||||||
dw_printf (" x x = FX.25 increase verbose level.\n");
|
dw_printf (" x x = FX.25 increase verbose level.\n");
|
||||||
|
dw_printf (" d d = APRStt (DTMF to APRS object translation).\n");
|
||||||
dw_printf (" -q Quiet (suppress output) options:\n");
|
dw_printf (" -q Quiet (suppress output) options:\n");
|
||||||
dw_printf (" h h = Heard line with the audio level.\n");
|
dw_printf (" h h = Heard line with the audio level.\n");
|
||||||
dw_printf (" d d = Decoding of APRS packets.\n");
|
dw_printf (" d d = Decoding of APRS packets.\n");
|
||||||
|
|
Loading…
Reference in New Issue