Skip to content

Commit 42314b7

Browse files
committed
gpsd 3.23 (API 12) compatibility and cleanups.
1 parent 5dbe2ce commit 42314b7

File tree

5 files changed

+105
-72
lines changed

5 files changed

+105
-72
lines changed

CHANGES.md

+4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717

1818
- The BEACON configuration now recognizes the SOURCE= option. This replaces the AX.25 source address rather than using the MYCALL value for the channel. This is useful for sending more than 5 analog telemetry channels. Use two, or more, source addresses with up to 5 analog channels each.
1919

20+
- For more flexibility, the FX.25 transmit property can now be set individually by channel, rather than having a global setting for all channels. The -X on the command line applies only to channel 0. For other channels you need to add a new line to the configuration file.
2021

22+
> After: "CHANNEL 1" (or other channel)
23+
>
24+
> Add: "FX25TX 1" (or 16 or 32 or 64)
2125
2226

2327
## Version 1.6 -- October 2020 ##

src/ax25_link.c

+14
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
* Establish connections and transfer data in the proper
2727
* order with retries.
2828
*
29+
* Using the term "data link" is rather unfortunate because it causes
30+
* confusion to someone familiar with the OSI networking model.
31+
* This corresponds to the layer 4 transport, not layer 2 data link.
32+
*
2933
* Description:
3034
*
3135
* Typical sequence for establishing a connection
@@ -824,6 +828,11 @@ static ax25_dlsm_t *get_link_handle (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LE
824828
// Create new data link state machine.
825829

826830
p = calloc (sizeof(ax25_dlsm_t), 1);
831+
if (p == NULL) {
832+
text_color_set(DW_COLOR_ERROR);
833+
dw_printf ("FATAL ERROR: Out of memory.\n");
834+
exit (EXIT_FAILURE);
835+
}
827836
p->magic1 = MAGIC1;
828837
p->start_time = dtime_now();
829838
p->stream_id = next_stream_id++;
@@ -1493,6 +1502,11 @@ void dl_register_callsign (dlq_item_t *E)
14931502
}
14941503

14951504
r = calloc(sizeof(reg_callsign_t),1);
1505+
if (r == NULL) {
1506+
text_color_set(DW_COLOR_ERROR);
1507+
dw_printf ("FATAL ERROR: Out of memory.\n");
1508+
exit (EXIT_FAILURE);
1509+
}
14961510
strlcpy (r->callsign, E->addrs[0], sizeof(r->callsign));
14971511
r->chan = E->chan;
14981512
r->client = E->client;

src/decode_aprs.c

+40-14
Original file line numberDiff line numberDiff line change
@@ -1377,9 +1377,14 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
13771377

13781378
#define isT(c) ((c) == ' ' || (c) == '>' || (c) == ']' || (c) == '`' || (c) == '\'')
13791379

1380-
// Last updated Sept. 2016 for TH-D74A
1380+
// Last Updated Dec. 2021
1381+
1382+
// This does not change very often but I'm wondering if we could simply parse
1383+
// http://www.aprs.org/aprs12/mic-e-types.txt similar to how we use tocalls.txt.
13811384

13821385
if (isT(*pfirst)) {
1386+
1387+
// "legacy" formats.
13831388

13841389
if (*pfirst == ' ' ) { strlcpy (A->g_mfr, "Original MIC-E", sizeof(A->g_mfr)); pfirst++; }
13851390

@@ -1390,6 +1395,8 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
13901395
else if (*pfirst == ']' && *plast == '=') { strlcpy (A->g_mfr, "Kenwood TM-D710", sizeof(A->g_mfr)); pfirst++; plast--; }
13911396
else if (*pfirst == ']' ) { strlcpy (A->g_mfr, "Kenwood TM-D700", sizeof(A->g_mfr)); pfirst++; }
13921397

1398+
// ` should be used for message capable devices.
1399+
13931400
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == ' ') { strlcpy (A->g_mfr, "Yaesu VX-8", sizeof(A->g_mfr)); pfirst++; plast-=2; }
13941401
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == '"') { strlcpy (A->g_mfr, "Yaesu FTM-350", sizeof(A->g_mfr)); pfirst++; plast-=2; }
13951402
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == '#') { strlcpy (A->g_mfr, "Yaesu VX-8G", sizeof(A->g_mfr)); pfirst++; plast-=2; }
@@ -1398,11 +1405,15 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
13981405
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == ')') { strlcpy (A->g_mfr, "Yaesu FTM-100D", sizeof(A->g_mfr)); pfirst++; plast-=2; }
13991406
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == '(') { strlcpy (A->g_mfr, "Yaesu FT2D", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14001407
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == '0') { strlcpy (A->g_mfr, "Yaesu FT3D", sizeof(A->g_mfr)); pfirst++; plast-=2; }
1408+
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == '3') { strlcpy (A->g_mfr, "Yaesu FT5D", sizeof(A->g_mfr)); pfirst++; plast-=2; }
1409+
else if (*pfirst == '`' && *(plast-1) == '_' && *plast == '1') { strlcpy (A->g_mfr, "Yaesu FTM-300D", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14011410

14021411
else if (*pfirst == '`' && *(plast-1) == ' ' && *plast == 'X') { strlcpy (A->g_mfr, "AP510", sizeof(A->g_mfr)); pfirst++; plast-=2; }
1412+
14031413
else if (*pfirst == '`' && *(plast-1) == '(' && *plast == '5') { strlcpy (A->g_mfr, "Anytone D578UV", sizeof(A->g_mfr)); pfirst++; plast-=2; }
1414+
else if (*pfirst == '`' ) { strlcpy (A->g_mfr, "Generic Mic-Emsg", sizeof(A->g_mfr)); pfirst++; }
14041415

1405-
else if (*pfirst == '`' ) { strlcpy (A->g_mfr, "Mic-Emsg", sizeof(A->g_mfr)); pfirst++; }
1416+
// ' should be used for trackers (not message capable).
14061417

14071418
else if (*pfirst == '\'' && *(plast-1) == '(' && *plast == '8') { strlcpy (A->g_mfr, "Anytone D878UV", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14081419

@@ -1412,13 +1423,13 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
14121423
else if (*pfirst == '\'' && *(plast-1) == ':' && *plast == '4') { strlcpy (A->g_mfr, "SCS GmbH & Co. P4dragon DR-7400 modems", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14131424
else if (*pfirst == '\'' && *(plast-1) == ':' && *plast == '8') { strlcpy (A->g_mfr, "SCS GmbH & Co. P4dragon DR-7800 modems", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14141425

1415-
else if (*pfirst == '\'' ) { strlcpy (A->g_mfr, "McTrackr", sizeof(A->g_mfr)); pfirst++; }
1426+
else if (*pfirst == '\'' ) { strlcpy (A->g_mfr, "Generic McTrackr", sizeof(A->g_mfr)); pfirst++; }
14161427

14171428
else if ( *(plast-1) == '\\' ) { strlcpy (A->g_mfr, "Hamhud ?", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14181429
else if ( *(plast-1) == '/' ) { strlcpy (A->g_mfr, "Argent ?", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14191430
else if ( *(plast-1) == '^' ) { strlcpy (A->g_mfr, "HinzTec anyfrog", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14201431
else if ( *(plast-1) == '*' ) { strlcpy (A->g_mfr, "APOZxx www.KissOZ.dk Tracker. OZ1EKD and OZ7HVO", sizeof(A->g_mfr)); pfirst++; plast-=2; }
1421-
else if ( *(plast-1) == '~' ) { strlcpy (A->g_mfr, "OTHER", sizeof(A->g_mfr)); pfirst++; plast-=2; }
1432+
else if ( *(plast-1) == '~' ) { strlcpy (A->g_mfr, "Unknown OTHER", sizeof(A->g_mfr)); pfirst++; plast-=2; }
14221433
}
14231434

14241435
/*
@@ -3486,6 +3497,8 @@ time_t get_timestamp (decode_aprs_t *A, char *p)
34863497
time_t ts;
34873498

34883499
ts = time(NULL);
3500+
// FIXME: use gmtime_r instead.
3501+
// Besides not being thread safe, gmtime could possibly return null.
34893502
ptm = gmtime(&ts);
34903503

34913504
pdhm = (void *)p;
@@ -4211,9 +4224,7 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen)
42114224
dw_printf("%s:%d: %s\n", __FILE__, __LINE__, emsg);
42124225
}
42134226

4214-
// TODO: Would like to restrict to even length something like this: ([!-{][!-{]){2,7}
4215-
4216-
e = regcomp (&base91_tel_re, "\\|([!-{]{4,14})\\|", REG_EXTENDED);
4227+
e = regcomp (&base91_tel_re, "\\|(([!-{][!-{]){2,7})\\|", REG_EXTENDED);
42174228
if (e) {
42184229
regerror (e, &base91_tel_re, emsg, sizeof(emsg));
42194230
dw_printf("%s:%d: %s\n", __FILE__, __LINE__, emsg);
@@ -4411,20 +4422,20 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen)
44114422

44124423
/*
44134424
* Telemetry data, in base 91 compressed format appears as 2 to 7 pairs
4414-
* of base 91 digits, surrounded by | at start and end.
4425+
* of base 91 digits, ! thru {, surrounded by | at start and end.
44154426
*/
44164427

44174428

44184429
if (regexec (&base91_tel_re, A->g_comment, MAXMATCH, match, 0) == 0)
44194430
{
44204431

4421-
char tdata[30]; /* Should be 4 to 14 characters. */
4432+
char tdata[30]; /* Should be even number of 4 to 14 characters. */
44224433

4423-
//dw_printf("compressed telemetry start=%d, end=%d\n", (int)(match[0].rm_so), (int)(match[0].rm_eo));
4434+
//dw_printf("compressed telemetry start=%d, end=%d\n", (int)(match[0].rm_so), (int)(match[0].rm_eo));
44244435

44254436
substr_se (tdata, A->g_comment, match[1].rm_so, match[1].rm_eo);
44264437

4427-
//dw_printf("compressed telemetry data = \"%s\"\n", tdata);
4438+
//dw_printf("compressed telemetry data = \"%s\"\n", tdata);
44284439

44294440
telemetry_data_base91 (A->g_src, tdata, A->g_telemetry, sizeof(A->g_telemetry));
44304441

@@ -4442,6 +4453,8 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen)
44424453
*
44434454
* It surprised me to see this in a MIC-E message.
44444455
* MIC-E has resolution of .01 minute so it would make sense to have it as an option.
4456+
* We also find an example in http://www.aprs.org/aprs12/mic-e-examples.txt
4457+
* 'abc123R/'123}FFF.FFFMHztext.../A=123456...!DAO! Mv
44454458
*/
44464459

44474460
if (regexec (&dao_re, A->g_comment, MAXMATCH, match, 0) == 0)
@@ -4451,7 +4464,7 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen)
44514464
int a = A->g_comment[match[0].rm_so+2];
44524465
int o = A->g_comment[match[0].rm_so+3];
44534466

4454-
//dw_printf("start=%d, end=%d\n", (int)(match[0].rm_so), (int)(match[0].rm_eo));
4467+
dw_printf("DAO start=%d, end=%d\n", (int)(match[0].rm_so), (int)(match[0].rm_eo));
44554468

44564469

44574470
/*
@@ -4503,7 +4516,7 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen)
45034516
*/
45044517

45054518
/*
4506-
* Here is an interesting case.
4519+
* Here are a couple situations where it is seen.
45074520
*
45084521
* W8SAT-1>T2UV0P:`qC<0x1f>l!Xu\'"69}WMNI EDS Response Unit #1|+/%0'n|!w:X!|3
45094522
*
@@ -4520,13 +4533,26 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen)
45204533
* Comment earlier points out that MIC-E format has resolution of 0.01 minute,
45214534
* same as non-compressed format, so the DAO does work out, after thinking
45224535
* about it for a while.
4536+
* We also find a MIC-E example with !DAO! here: http://www.aprs.org/aprs12/mic-e-examples.txt
4537+
*
4538+
* Another one:
4539+
*
4540+
* KS4FUN-12>3X0PRU,W6CX-3,BKELEY,WIDE2*:`2^=l!<0x1c>+/'"48}MT-RTG|%B%p'a|!wqR!|3
4541+
*
4542+
* MIC-E, Red Cross, Special
4543+
* N 38 00.2588, W 122 06.3354
4544+
* 0 MPH, course 100, alt 108 ft
4545+
* MT-RTG comment
4546+
* |%B%p'a| Seq=397, A1=443, A2=610
4547+
* !wqR! DAO
4548+
* |3 Byonics TinyTrack3
4549+
*
45234550
*/
45244551

45254552
/*
45264553
* The spec appears to be wrong. It says '}' is the maximum value when it should be '{'.
45274554
*/
45284555

4529-
45304556
if (isdigit91(a)) {
45314557
A->g_lat += (a - B91_MIN) * 1.1 / 600000.0 * sign(A->g_lat);
45324558
}

src/dwgpsd.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// This file is part of Dire Wolf, an amateur radio packet TNC.
33
//
4-
// Copyright (C) 2013, 2014, 2015, 2020 John Langner, WB2OSZ
4+
// Copyright (C) 2013, 2014, 2015, 2020, 2022 John Langner, WB2OSZ
55
//
66
// This program is free software: you can redistribute it and/or modify
77
// it under the terms of the GNU General Public License as published by
@@ -60,7 +60,11 @@
6060
// An incompatibility was introduced with version 7
6161
// and again with 9 and again with 10.
6262

63-
#if GPSD_API_MAJOR_VERSION < 5 || GPSD_API_MAJOR_VERSION > 11
63+
// release lib version API Raspberry Pi OS
64+
// 3.22 28 11 bullseye
65+
// 3.23 29 12
66+
67+
#if GPSD_API_MAJOR_VERSION < 5 || GPSD_API_MAJOR_VERSION > 12
6468
#error libgps API version might be incompatible.
6569
#endif
6670

@@ -364,6 +368,10 @@ static void * read_gpsd_thread (void *arg)
364368
default:
365369
case MODE_NOT_SEEN:
366370
case MODE_NO_FIX:
371+
if (info.fix <= DWFIX_NOT_SEEN) {
372+
text_color_set(DW_COLOR_INFO);
373+
dw_printf ("GPSD: No location fix.\n");
374+
}
367375
if (info.fix >= DWFIX_2D) {
368376
text_color_set(DW_COLOR_INFO);
369377
dw_printf ("GPSD: Lost location fix.\n");

0 commit comments

Comments
 (0)