diff --git a/CHANGES.md b/CHANGES.md index 4761cf2..3e64700 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,7 +3,7 @@ ---------- -## Version 1.3 -- Beta Test -- February 2016 ## +## Version 1.3 -- Beta Test -- March 2016 ## ### New Features: ### @@ -40,7 +40,7 @@ command line option. - When receiving packet with comment of a few hundred characters. - - Address in path, from Internet server. more than 9 characters. + - Address in path, from Internet server, more than 9 characters. - "INTERNAL ERROR: dlq_append NULL packet pointer." when using PASSALL. @@ -51,6 +51,8 @@ command line option. - AGW network protocol now works properly for big-endian processors such as PowerPC or MIPS. +- Packet filtering treated telemetry metadata as messages rather than telemetry. + ---------- ## Version 1.2 -- June 2015 ## diff --git a/Makefile.linux b/Makefile.linux index be9bd59..db78d16 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -234,7 +234,7 @@ direwolf : direwolf.o config.o recv.o demod.o dsp.o demod_afsk.o demod_9600.o hd decode_aprs.o symbols.o server.o kiss.o kissnet.o kiss_frame.o hdlc_send.o fcs_calc.o \ gen_tone.o audio.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o morse.o \ ptt.o beacon.o encode_aprs.o latlong.o encode_aprs.o latlong.o textcolor.o \ - dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o nmea.o serial_port.o log.o telemetry.o \ + dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o waypoint.o serial_port.o log.o telemetry.o \ dwgps.o dwgpsnmea.o dwgpsd.o dtime_now.o \ misc.a geotranz.a $(CC) -o $@ $^ $(LDFLAGS) diff --git a/Makefile.macosx b/Makefile.macosx index c0fc4e7..12c94c1 100644 --- a/Makefile.macosx +++ b/Makefile.macosx @@ -226,7 +226,7 @@ direwolf : direwolf.o aprs_tt.o audio_portaudio.o audio_stats.o ax25_pad.o beaco encode_aprs.o encode_aprs.o fcs_calc.o fcs_calc.o gen_tone.o \ geotranz.a hdlc_rec.o hdlc_rec2.o hdlc_send.o igate.o kiss_frame.o \ kiss.o kissnet.o latlong.o latlong.o log.o morse.o multi_modem.o \ - nmea.o serial_port.o pfilter.o ptt.o rdq.o recv.o redecode.o rrbb.o server.o \ + waypoint.o serial_port.o pfilter.o ptt.o rdq.o recv.o redecode.o rrbb.o server.o \ symbols.o telemetry.o textcolor.o tq.o tt_text.o tt_user.o xmit.o \ dwgps.o dwgpsnmea.o $(CC) $(CFLAGS) -o $@ $^ -lpthread $(LDLIBS) -lm diff --git a/Makefile.win b/Makefile.win index ee6c75d..d62e414 100644 --- a/Makefile.win +++ b/Makefile.win @@ -72,7 +72,7 @@ direwolf : direwolf.o config.o recv.o demod.o dsp.o demod_afsk.o demod_9600.o hd decode_aprs.o symbols.o server.o kiss.o kissnet.o kiss_frame.o hdlc_send.o fcs_calc.o \ gen_tone.o morse.o audio_win.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o \ ptt.o beacon.o dwgps.o encode_aprs.o latlong.o textcolor.o \ - dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o nmea.o serial_port.o log.o telemetry.o \ + dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o waypoint.o serial_port.o log.o telemetry.o \ dwgps.o dwgpsnmea.o dtime_now.o \ dw-icon.o regex.a misc.a geotranz.a $(CC) $(CFLAGS) -o $@ $^ -lwinmm -lws2_32 diff --git a/README.md b/README.md index 8a457b3..451b043 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ In the early days of Amateur Packet Radio, it was necessary to use a “Terminal Node Controller” (TNC) with specialized hardware. Those days are gone. You can now get better results at lower cost by connecting your radio to the “soundcard” interface of a computer and using software to decode the signals. -Dire Wolf is a software "soundcard" modem/TNC and [APRS](http://www.aprs.org/) encoder/decoder. It can be used stand-alone to observe APRS traffic, as a digipeater, [APRStt](http://www.aprs.org/aprstt.html) gateway, or Internet Gateway (IGate). It can also be used as a virtual TNC for other applications such as [APRSIS32](http://aprsisce.wikidot.com/), [UI-View32](http://www.ui-view.net/), [Xastir](http://xastir.org/index.php/Main_Page), [APRS-TW](http://aprstw.blandranch.net/), [YAAC](http://www.ka2ddo.org/ka2ddo/YAAC.html), [UISS](http://users.belgacom.net/hamradio/uiss.htm), [Linux AX25](http://www.linux-ax25.org/wiki/Main_Page), [SARTrack](http://www.sartrack.co.nz/index.html), [RMS Express](http://www.winlink.org/RMSExpress), and many others. +Dire Wolf is a software "soundcard" modem/TNC and [APRS](http://www.aprs.org/) encoder/decoder. It can be used stand-alone to observe APRS traffic, as a digipeater, [APRStt](http://www.aprs.org/aprstt.html) gateway, or Internet Gateway (IGate). It can also be used as a virtual TNC for other applications such as [APRSIS32](http://aprsisce.wikidot.com/), [UI-View32](http://www.ui-view.net/), [Xastir](http://xastir.org/index.php/Main_Page), [APRS-TW](http://aprstw.blandranch.net/), [YAAC](http://www.ka2ddo.org/ka2ddo/YAAC.html), [UISS](http://users.belgacom.net/hamradio/uiss.htm), [Linux AX25](http://www.linux-ax25.org/wiki/Main_Page), [SARTrack](http://www.sartrack.co.nz/index.html), [RMS Express](http://www.winlink.org/RMSExpress), [BPQ32](http://www.cantab.net/users/john.wiseman/Documents/BPQ32.html), and many others. ## Features ## diff --git a/config.c b/config.c index 8090c85..3e35590 100644 --- a/config.c +++ b/config.c @@ -753,8 +753,10 @@ void config_init (char *fname, struct audio_s *p_audio_config, //strlcpy (p_misc_config->nullmodem, DEFAULT_NULLMODEM, sizeof(p_misc_config->nullmodem)); strlcpy (p_misc_config->nullmodem, "", sizeof(p_misc_config->nullmodem)); + strlcpy (p_misc_config->gpsnmea_port, "", sizeof(p_misc_config->gpsnmea_port)); - strlcpy (p_misc_config->nmea_port, "", sizeof(p_misc_config->nmea_port)); + strlcpy (p_misc_config->waypoint_port, "", sizeof(p_misc_config->waypoint_port)); + strlcpy (p_misc_config->logdir, "", sizeof(p_misc_config->logdir)); @@ -1674,10 +1676,8 @@ void config_init (char *fname, struct audio_s *p_audio_config, */ else if (strcasecmp(t, "TXINH") == 0) { - int it; char itname[8]; - it = ICTYPE_TXINH; strlcpy (itname, "TXINH", sizeof(itname)); t = split(NULL,0); @@ -1701,14 +1701,14 @@ void config_init (char *fname, struct audio_s *p_audio_config, } if (*t == '-') { - p_audio_config->achan[channel].ictrl[it].gpio = atoi(t+1); - p_audio_config->achan[channel].ictrl[it].invert = 1; + p_audio_config->achan[channel].ictrl[ICTYPE_TXINH].gpio = atoi(t+1); + p_audio_config->achan[channel].ictrl[ICTYPE_TXINH].invert = 1; } else { - p_audio_config->achan[channel].ictrl[it].gpio = atoi(t); - p_audio_config->achan[channel].ictrl[it].invert = 0; + p_audio_config->achan[channel].ictrl[ICTYPE_TXINH].gpio = atoi(t); + p_audio_config->achan[channel].ictrl[ICTYPE_TXINH].invert = 0; } - p_audio_config->achan[channel].ictrl[it].method = PTT_METHOD_GPIO; + p_audio_config->achan[channel].ictrl[ICTYPE_TXINH].method = PTT_METHOD_GPIO; #endif } } @@ -3828,18 +3828,46 @@ void config_init (char *fname, struct audio_s *p_audio_config, } /* - * NMEA - Device name for communication with NMEA device. - * Wasn't documented will probably use WAYPOINT instead. + * WAYPOINT - Generate WPT NMEA sentences for display on map. + * + * WAYPOINT serial-device [ formats ] + * */ - else if (strcasecmp(t, "nmea") == 0) { + else if (strcasecmp(t, "waypoint") == 0) { t = split(NULL,0); if (t == NULL) { text_color_set(DW_COLOR_ERROR); - dw_printf ("Config file: Missing device name for NMEA port on line %d.\n", line); + dw_printf ("Config file: Missing device name for WAYPOINT on line %d.\n", line); continue; } else { - strlcpy (p_misc_config->nmea_port, t, sizeof(p_misc_config->nmea_port)); + strlcpy (p_misc_config->waypoint_port, t, sizeof(p_misc_config->waypoint_port)); + } + t = split(NULL,1); + if (t != NULL) { + for ( ; *t != '\0' ; t++ ) { + switch (toupper(*t)) { + case 'N': + p_misc_config->waypoint_formats |= WPT_FORMAT_NMEA_GENERIC; + break; + case 'G': + p_misc_config->waypoint_formats |= WPT_FORMAT_GARMIN; + break; + case 'M': + p_misc_config->waypoint_formats |= WPT_FORMAT_MAGELLAN; + break; + case 'K': + p_misc_config->waypoint_formats |= WPT_FORMAT_KENWOOD; + break; + case ' ': + case ',': + break; + default: + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file: Invalid output format '%c' for WAYPOINT on line %d.\n", *t, line); + break; + } + } } } diff --git a/config.h b/config.h index 4ea2eda..acfb47a 100644 --- a/config.h +++ b/config.h @@ -43,6 +43,7 @@ struct misc_config_s { char gpsnmea_port[20]; /* Serial port name for reading NMEA sentences from GPS. */ /* e.g. COM22, /dev/ttyACM0 */ + /* Currently no option for setting non-standard speed. */ char gpsd_host[20]; /* Host for gpsd server. */ /* e.g. localhost, 192.168.1.2 */ @@ -50,9 +51,19 @@ struct misc_config_s { int gpsd_port; /* Port number for gpsd server. */ /* Default is 2947. */ + + char waypoint_port[20]; /* Serial port name for sending NMEA waypoint sentences */ + /* to a GPS map display or other mapping application. */ /* e.g. COM22, /dev/ttyACM0 */ - char nmea_port[20]; /* Serial port name for NMEA communication with GPS */ - /* receiver and/or mapping application. Change this. */ + /* Currently no option for setting non-standard speed. */ + + int waypoint_formats; /* Which sentence formats should be generated? */ + +#define WPT_FORMAT_NMEA_GENERIC 0x01 /* N $GPWPT */ +#define WPT_FORMAT_GARMIN 0x02 /* G $PGRMW */ +#define WPT_FORMAT_MAGELLAN 0x04 /* M $PMGNWPL */ +#define WPT_FORMAT_KENWOOD 0x08 /* K $PKWDWPL */ + char logdir[80]; /* Directory for saving activity logs. */ diff --git a/direwolf.c b/direwolf.c index f1126b6..6cf34a1 100644 --- a/direwolf.c +++ b/direwolf.c @@ -89,7 +89,7 @@ #include "kiss.h" #include "kissnet.h" #include "kiss_frame.h" -#include "nmea.h" +#include "waypoint.h" #include "gen_tone.h" #include "digipeater.h" #include "tq.h" @@ -103,6 +103,7 @@ #include "igate.h" #include "symbols.h" #include "dwgps.h" +#include "waypoint.h" #include "log.h" #include "recv.h" #include "morse.h" @@ -162,6 +163,7 @@ static int q_h_opt = 0; /* "-q h" Quiet, suppress the "heard" line with audio static int q_d_opt = 0; /* "-q d" Quiet, suppress the decoding of APRS packets. */ + static struct misc_config_s misc_config; @@ -236,8 +238,8 @@ int main (int argc, char *argv[]) text_color_init(t_opt); text_color_set(DW_COLOR_INFO); - dw_printf ("Dire Wolf version %d.%d (%s) Beta Test\n", MAJOR_VERSION, MINOR_VERSION, __DATE__); - //dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "K", __DATE__); + //dw_printf ("Dire Wolf version %d.%d (%s) Beta Test\n", MAJOR_VERSION, MINOR_VERSION, __DATE__); + dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "A", __DATE__); //dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION); #if defined(ENABLE_GPSD) || defined(USE_HAMLIB) @@ -451,9 +453,9 @@ int main (int argc, char *argv[]) // separate out gps & waypoints. case 'g': d_g_opt++; break; + case 'w': waypoint_set_debug (1); break; // not documented yet. case 't': d_t_opt++; beacon_tracker_set_debug (d_t_opt); break; - case 'w': nmea_set_debug (1); break; // not documented yet. case 'p': d_p_opt = 1; break; // TODO: packet dump for xmit side. case 'o': d_o_opt++; ptt_set_debug(d_o_opt); break; case 'i': d_i_opt++; break; @@ -698,7 +700,7 @@ int main (int argc, char *argv[]) */ dwgps_init (&misc_config, d_g_opt); - nmea_init (&misc_config); // TODO: revisit. + waypoint_init (&misc_config); /* * Create thread for trying to salvage frames with bad FCS. @@ -946,7 +948,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev // Convert to NMEA waypoint sentence if we have a location. if (A.g_lat != G_UNKNOWN && A.g_lon != G_UNKNOWN) { - nmea_send_waypoint (strlen(A.g_name) > 0 ? A.g_name : A.g_src, + waypoint_send_sentence (strlen(A.g_name) > 0 ? A.g_name : A.g_src, A.g_lat, A.g_lon, A.g_symbol_table, A.g_symbol_code, DW_FEET_TO_METERS(A.g_altitude_ft), A.g_course, DW_MPH_TO_KNOTS(A.g_speed_mph), A.g_comment); @@ -1026,6 +1028,7 @@ static BOOL cleanup_win (int ctrltype) dw_printf ("\nQRT\n"); log_term (); ptt_term (); + waypoint_term (); dwgps_term (); SLEEP_SEC(1); ExitProcess (0); diff --git a/dwgpsnmea.c b/dwgpsnmea.c index 0de0512..93de1ed 100644 --- a/dwgpsnmea.c +++ b/dwgpsnmea.c @@ -47,7 +47,8 @@ static int s_debug = 0; /* Enable debug output. */ /* See dwgpsnmea_init description for values. */ - + +static struct misc_config_s *s_save_configp; @@ -109,6 +110,8 @@ int dwgpsnmea_init (struct misc_config_s *pconfig, int debug) #endif s_debug = debug; + s_save_configp = pconfig; + if (s_debug >= 2) { text_color_set(DW_COLOR_DEBUG); @@ -160,6 +163,19 @@ int dwgpsnmea_init (struct misc_config_s *pconfig, int debug) } /* end dwgpsnmea_init */ +/* Return fd to share if waypoint wants same device. */ +/* Currently both are fixed speed at 4800. */ +/* If that ever becomes configurable, that needs to be compared too. */ + +MYFDTYPE dwgpsnmea_get_fd(char *wp_port_name, int speed) +{ + if (strcmp(s_save_configp->gpsnmea_port, wp_port_name) == 0 && speed == 4800) { + return (s_gpsnmea_port_fd); + } + return (MYFDERROR); +} + + /*------------------------------------------------------------------- * * Name: read_gpsnmea_thread diff --git a/dwgpsnmea.h b/dwgpsnmea.h index a126a50..ffe5a12 100644 --- a/dwgpsnmea.h +++ b/dwgpsnmea.h @@ -1,5 +1,5 @@ -/* dwgpsnmea.h - For NMEA sentences over serial port */ +/* dwgpsnmea.h - For reading NMEA sentences over serial port */ @@ -8,10 +8,13 @@ #include "dwgps.h" /* for dwfix_t */ #include "config.h" +#include "serial_port.h" /* for MYFDTYPE */ int dwgpsnmea_init (struct misc_config_s *pconfig, int debug); +MYFDTYPE dwgpsnmea_get_fd(char *wp_port_name, int speed); + void dwgpsnmea_term (void); @@ -19,6 +22,7 @@ dwfix_t dwgpsnmea_gprmc (char *sentence, int quiet, double *odlat, double *odlon dwfix_t dwgpsnmea_gpgga (char *sentence, int quiet, double *odlat, double *odlon, float *oalt, int *onsat); + #endif diff --git a/man1/direwolf.1 b/man1/direwolf.1 index b81b8a2..36beb64 100644 --- a/man1/direwolf.1 +++ b/man1/direwolf.1 @@ -79,6 +79,8 @@ p = Packet dump in hexadecimal. .P g = GPS interface. .P +W = Waypoints for position or object reports. +.P t = Tracker beacon. .P o = Output controls such as PTT and DCD. diff --git a/mgn_icon.h b/mgn_icon.h index 3c96aab..4563cce 100644 --- a/mgn_icon.h +++ b/mgn_icon.h @@ -5,9 +5,18 @@ * * Waypoint icon codes for use in the $PMGNWPL sentence. * - * Derived from Data Transmission Protocol For Magellan Products - version 2.11 + * Derived from Data Transmission Protocol For Magellan Products - version 2.11, March 2003 + * + * http://www.gpsinformation.org/mag-proto-2-11.pdf + * + * + * That's 13 years ago. There should be something newer available but I can't find it. + * + * The is based on the newer models at the time. Earlier models had shorter incompatible icon lists. */ + + #define MGN_crossed_square "a" #define MGN_box "b" #define MGN_house "c" @@ -110,7 +119,7 @@ static const char mgn_primary_symtab[SYMTAB_SIZE][3] = { MGN_default, // E 37 EYEBALL (Eye catcher!) MGN_default, // F 38 Farm Vehicle (tractor) MGN_default, // G 39 Grid Square (6 digit) - MGN_default, // H 40 HOTEL (blue bed symbol) + MGN_hotel, // H 40 HOTEL (blue bed symbol) MGN_aerial, // I 41 TcpIp on air network stn MGN_default, // J 42 MGN_default, // K 43 School @@ -150,7 +159,7 @@ static const char mgn_primary_symtab[SYMTAB_SIZE][3] = { MGN_aerial, // m 77 Mic-E Repeater MGN_default, // n 78 Node (black bulls-eye) MGN_default, // o 79 EOC - MGN_default, // p 80 ROVER (puppy, or dog) + MGN_zoo, // p 80 ROVER (puppy, or dog) MGN_default, // q 81 GRID SQ shown above 128 m MGN_aerial, // r 82 Repeater MGN_default, // s 83 SHIP (pwr boat) @@ -202,7 +211,7 @@ static const char mgn_alternate_symtab[SYMTAB_SIZE][3] = { MGN_default, // > 30 OVERLAYED CAR MGN_tourist_info, // ? 31 INFO Kiosk (Blue box with ?) MGN_default, // @ 32 HURICANE/Trop-Storm - MGN_default, // A 33 overlayBOX DTMF & RFID & XO + MGN_box, // A 33 overlayBOX DTMF & RFID & XO MGN_default, // B 34 Blwng Snow (& future codes) MGN_boating, // C 35 Coast Guard MGN_default, // D 36 Drizzle (proposed APRStt) @@ -215,7 +224,7 @@ static const char mgn_alternate_symtab[SYMTAB_SIZE][3] = { MGN_default, // K 43 Kenwood HT (W) MGN_lighthouse, // L 44 Lighthouse MGN_default, // M 45 MARS (A=Army,N=Navy,F=AF) - MGN_nav_aid, // N 46 Navigation Buoy + MGN_buoy, // N 46 Navigation Buoy MGN_airport, // O 47 Rocket MGN_default, // P 48 Parking MGN_default, // Q 49 QUAKE @@ -223,7 +232,7 @@ static const char mgn_alternate_symtab[SYMTAB_SIZE][3] = { MGN_aerial, // S 51 Satellite/Pacsat MGN_default, // T 52 Thunderstorm MGN_default, // U 53 SUNNY - MGN_default, // V 54 VORTAC Nav Aid + MGN_nav_aid, // V 54 VORTAC Nav Aid MGN_default, // W 55 # NWS site (NWS options) MGN_default, // X 56 Pharmacy Rx (Apothicary) MGN_aerial, // Y 57 Radios and devices @@ -242,7 +251,7 @@ static const char mgn_alternate_symtab[SYMTAB_SIZE][3] = { MGN_default, // f 70 Funnel Cloud MGN_default, // g 71 Gale Flags MGN_default, // h 72 Store. or HAMFST Hh=HAM store - MGN_default, // i 73 BOX or points of Interest + MGN_box, // i 73 BOX or points of Interest MGN_default, // j 74 WorkZone (Steam Shovel) MGN_default, // k 75 Special Vehicle SUV,ATV,4x4 MGN_default, // l 76 Areas (box,circles,etc) diff --git a/nmea.c b/nmea.c deleted file mode 100644 index 32e487e..0000000 --- a/nmea.c +++ /dev/null @@ -1,465 +0,0 @@ -// -// This file is part of Dire Wolf, an amateur radio packet TNC. -// -// Copyright (C) 2014, 2015 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 -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - - -//#define DEBUG 1 - - -// TODO: rename this to waypoint & integrate. - -/*------------------------------------------------------------------ - * - * Module: nmea.c - * - * Purpose: Receive NMEA sentences from a GPS receiver. - * Send NMEA waypoint sentences to GPS display or mapping application. - * - *---------------------------------------------------------------*/ - -#include -#include - -#if __WIN32__ -#include -#include -#else -#define __USE_XOPEN2KXSI 1 -#define __USE_XOPEN 1 -//#define __USE_POSIX 1 -#include -#include -#include -#include -#include -#include -#include -#endif - -#include -#include - -#if __WIN32__ -char *strsep(char **stringp, const char *delim); -#endif - -#include "direwolf.h" -#include "config.h" -#include "ax25_pad.h" -#include "textcolor.h" -//#include "xmit.h" -#include "latlong.h" -#include "nmea.h" -#include "grm_sym.h" /* Garmin symbols */ -#include "mgn_icon.h" /* Magellan icons */ -#include "serial_port.h" - - -// TODO: receive buffer... static kiss_frame_t kf; /* Accumulated KISS frame and state of decoder. */ - -static MYFDTYPE nmea_port_fd = MYFDERROR; - -static void nmea_send_sentence (char *sent); - - - -//static void nmea_parse_gps (char *sentence); - - -static int nmea_debug = 0; /* Print information flowing from and to attached device. */ - -void nmea_set_debug (int n) -{ - nmea_debug = n; -} - - -/*------------------------------------------------------------------- - * - * Name: nmea_init - * - * Purpose: Initialization for NMEA communication port. - * - * Inputs: mc->nmea_port - name of serial port. - * - * Global output: nmea_port_fd - * - * - * Description: (1) Open serial port device. - * - *---------------------------------------------------------------*/ - - -void nmea_init (struct misc_config_s *mc) -{ - -/* - * Open serial port connection. - * 4800 baud is standard for GPS. - * Should add an option to allow changing someday. - */ - if (strlen(mc->nmea_port) > 0) { - - nmea_port_fd = serial_port_open (mc->nmea_port, 4800); - - - } - - -#if DEBUG - text_color_set (DW_COLOR_DEBUG); - - dw_printf ("end of nmea_init: nmea_port_fd = %d\n", nmea_port_fd); -#endif -} - - - -/*------------------------------------------------------------------- - * - * Name: append_checksum - * - * Purpose: Append checksum to the sentence. - * - * In/out: sentence - NMEA sentence beginning with '$'. - * - * Description: Checksum is exclusive of characters except leading '$'. - * We append '*' and an upper case two hexadecimal value. - * - *--------------------------------------------------------------------*/ - -static void append_checksum (char *sentence) -{ - char *p; - int cs; - - assert (sentence[0] == '$'); - - cs = 0; - for (p = sentence+1; *p != '\0'; p++) { - cs ^= *p; - } - - sprintf (p, "*%02X", cs & 0xff); - -// Add crlf too? - -} /* end append_checksum */ - - - -/*------------------------------------------------------------------- - * - * Name: nema_send_waypoint - * - * Purpose: Convert APRS position or object into NMEA waypoint sentence - * for use by a GPS display or other mapping application. - * - * Inputs: wname_in - Name of waypoint. - * dlat - Latitude. - * dlong - Longitude. - * symtab - Symbol table or overlay character. - * symbol - Symbol code. - * alt - Altitude in meters or G_UNKOWN. - * course - Course in degrees or ??? for unknown. - * speed - Speed in knots ?? or ?? - * comment - Description or message. - * - * - * Description: Currently we send multiple styles. Maybe someday there might - * be an option to send a selected subset. - * - * $GPWPL - Generic with only location and name. - * $PGRMW - Garmin, adds altitude, symbol, and comment - * to previously named waypoint. - * $PMGNWPL - Magellan, more complete for stationary objects. - * $PKWDWPL - Kenwood with APRS style symbol but missing comment. - * - *--------------------------------------------------------------------*/ - - -void nmea_send_waypoint (char *wname_in, double dlat, double dlong, char symtab, char symbol, - float alt, float course, float speed, char *comment) -{ - char wname[12]; /* Waypoint name. Any , or * removed. */ - char slat[12]; /* DDMM.mmmm */ - char slat_ns[2]; /* N or S */ - char slong[12]; /* DDDMM.mmmm */ - char slong_ew[2]; /* E or W */ - char sentence[500]; - char salt[12]; /* altitude as string, empty if unknown */ - char sspeed[12]; /* speed as string, empty if unknown */ - char scourse[12]; /* course as string, empty if unknown */ - int grm_sym; /* Garmin symbol code. */ - char sicon[5]; /* Magellan icon string */ - char stime[8]; - char sdate[8]; - char *p; - - - -// Remove any comma from name. - -// TODO: remove any , or * from comment. - - strcpy (wname, wname_in); - for (p=wname; *p != '\0'; p++) { - if (*p == ',') *p = ' '; - if (*p == '*') *p = ' '; - } - -// Convert position to character form. - - latitude_to_nmea (dlat, slat, slat_ns); - longitude_to_nmea (dlong, slong, slong_ew); - -/* - * Generic. - * - * $GPWPL,ddmm.mmmm,ns,dddmm.mmmm,ew,wname*99 - * - * Where, - * ddmm.mmmm,ns is latitude - * dddmm.mmmm,ew is longitude - * wname is the waypoint name - * *99 is checksum - */ - - snprintf (sentence, sizeof(sentence), "$GPWPL,%s,%s,%s,%s,%s", slat, slat_ns, slong, slong_ew, wname); - append_checksum (sentence); - nmea_send_sentence (sentence); - - - -/* - * Garmin - https://www8.garmin.com/support/pdf/NMEA_0183.pdf - * http://gpsinformation.net/mag-proto.htm - * - * $PGRMW,wname,alt,symbol,comment*99 - * - * Where, - * - * wname is waypoint name. Must match existing waypoint. - * alt is altitude in meters. - * symbol is symbol code. Hexadecimal up to FFFF. - * See Garmin Device Interface Specification 001-0063-00. - * comment is comment for the waypoint. - * *99 is checksum - */ - - if (alt == G_UNKNOWN) { - strcpy (salt, ""); - } - else { - snprintf (salt, sizeof(salt), "%.1f", alt); - } - grm_sym = 0x1234; // TODO - - snprintf (sentence, sizeof(sentence), "$PGRMW,%s,%s,%04X,%s", wname, salt, grm_sym, comment); - append_checksum (sentence); - nmea_send_sentence (sentence); - -/* - * Magellan - http://www.gpsinformation.org/mag-proto-2-11.pdf - * - * $PMGNWPL,ddmm.mmmm,ns,dddmm.mmmm,ew,alt,unit,wname,comment,icon,xx*99 - * - * Where, - * ddmm.mmmm,ns is latitude - * dddmm.mmmm,ew is longitude - * alt is altitude - * unit is M for meters or F for feet - * wname is the waypoint name - * comment is message or comment - * icon is one or two letters for icon code - * xx is waypoint type which is optional, not well - * defined, and not used in their example. - * *99 is checksum - */ - -// TODO: icon - - snprintf (sicon, sizeof(sicon), "??"); - snprintf (sentence, sizeof(sentence), "$PMGNWPL,%s,%s,%s,%s,%s,M,%s,%s,%s", - slat, slat_ns, slong, slong_ew, salt, wname, comment, sicon); - append_checksum (sentence); - nmea_send_sentence (sentence); - -/* - * Kenwood - Speculation due to no official spec found so far. - * - * $PKWDWPL,hhmmss,v,ddmm.mmmm,ns,dddmm.mmmm,ew,speed,course,ddmmyy,alt,wname,ts*99 - * - * Where, - * hhmmss is time in UTC. Should we supply current - * time or only pass along time from - * received signal? - * v indicates valid data ????????????????? - * Why would we send if not valid? - * ddmm.mmmm,ns is latitude - * dddmm.mmmm,ew is longitude - * speed is speed in UNITS ??? knots ????? - * course is course in degrees - * ddmmyy is date. Same question as time. - * alt is altitude. in UNITS ??? meters ??? - * wname is the waypoint name - * ts are the table and symbol. - * Non-standard parsing would be required - * to deal with these for symbol: - * , Boy Scouts / Girl Scouts - * * SnowMobile / Snow - * *99 is checksum - * - * Oddly, there is not place for comment. - */ - - if (speed == G_UNKNOWN) { - strcpy (sspeed, ""); - } - else { - snprintf (sspeed, sizeof(sspeed), "%.1f", speed); - } - if (course == G_UNKNOWN) { - strcpy (scourse, ""); - } - else { - snprintf (scourse, sizeof(scourse), "%.1f", course); - } - -// TODO: how to handle time & date ??? - - strcpy (stime, "123456"); - strcpy (sdate, "123456"); - - snprintf (sentence, sizeof(sentence), "$PKWDWPL,%s,V,%s,%s,%s,%s,%s,%s,%s,%s,%s,%c%c", - stime, slat, slat_ns, slong, slong_ew, - sspeed, scourse, sdate, salt, wname, symtab, symbol); - append_checksum (sentence); - nmea_send_sentence (sentence); - -/* - * One application recognizes these. Not implemented at this time. - * - * $GPTLL,01,ddmm.mmmm,ns,dddmm.mmmm,ew,tname,000000.00,T,R*99 - * - * Where, - * ddmm.mmmm,ns is latitude - * dddmm.mmmm,ew is longitude - * tname is the target name - * 000000.00 is timestamp ??? - * T is target status (S for need help) - * R is reference target ??? - * *99 is checksum - * - * - * $GPTXT,01,01,tname,message*99 - * - * Where, - * - * 01 is total number of messages in transmission - * 01 is message number in this transmission - * tname is target name. Should match name in WPL or TTL. - * message is the message. - * *99 is checksum - * - */ - -} /* end nmea_send_waypoint */ - - -#if 0 - -* d710a menu 603 $GPWPL $PMGNWPL $PKWDWPL - -symbol mapping - -https://freepository.com:444/50lItuLQ7fW6s-web/browser/Tracker2/trunk/sources/waypoint.c?rev=108 - - - -Data Transmission Protocol For Magellan Products - version 2.11 - - - - - - -$PMGNWPL,4651.529,N,07111.425,W,0000000,M,GC5A5F, GC. The straight line,a*13 - $PMGNWPL,3549.499,N,08650.827,W,0000257,M,HOME,HOME,c*4D - -http://gpsbabel.sourcearchive.com/documentation/1.3.7~cvs1/magproto_8c-source.html - - sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", - &latdeg,&latdir, - &lngdeg,&lngdir, - &alt,&altunits,shortname,descr); then icon - - snprintf(obuf, sizeof(), "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.0f,M,%-.*s,%-.46s,%s", - lat, ilat < 0 ? 'S' : 'N', - lon, ilon < 0 ? 'W' : 'E', - waypointp->altitude == unknown_alt ? - 0 : waypointp->altitude, - wpt_len, - owpt, - odesc, - icon_token); - -https://freepository.com:444/50lItuLQ7fW6s-web/changeset/108/Tracker2/trunk/sources/waypoint.c - -$PMGNWPL,4106.003,S,14640.214,E,0000069,M,KISSING SPOT,,a*3C - - - - - - * -https://freepository.com:444/50lItuLQ7fW6s-web/changeset/325 - - -#endif - - -static void nmea_send_sentence (char *sent) -{ - - int err; - int len = strlen(sent); - - - if (nmea_port_fd == MYFDERROR) { - return; - } - - text_color_set(DW_COLOR_XMIT); - dw_printf ("%s\n", sent); - - if (nmea_debug) { - // TODO: debugg out... nmea_debug_print (TO_CLIENT, NULL, nmea_buff+1, nmea_len-2); - } - -// TODO: need to append CR LF. - - serial_port_write (nmea_port_fd, sent, len); - -} /* nmea_send_sentence */ - - - - - -/* end nmea.c */ diff --git a/nmea.h b/nmea.h deleted file mode 100644 index 9ff8553..0000000 --- a/nmea.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* - * Name: nmea.h - */ - - -#include "ax25_pad.h" /* for packet_t */ - -#include "config.h" /* for struct misc_config_s */ - - -void nmea_init (struct misc_config_s *misc_config); - -void nmea_set_debug (int n); - -void nmea_send_waypoint (char *wname_in, double dlat, double dlong, char symtab, char symbol, - float alt, float course, float speed, char *comment); - -/* end nmea.h */ diff --git a/serial_port.h b/serial_port.h index 6c3287a..05ee072 100644 --- a/serial_port.h +++ b/serial_port.h @@ -1,6 +1,9 @@ /* serial_port.h */ +#ifndef SERIAL_PORT_H +#define SERIAL_PORT_H 1 + #if __WIN32__ @@ -24,4 +27,7 @@ extern int serial_port_write (MYFDTYPE fd, char *str, int len); extern int serial_port_get1 (MYFDTYPE fd); -extern void serial_port_close (MYFDTYPE fd); \ No newline at end of file +extern void serial_port_close (MYFDTYPE fd); + + +#endif \ No newline at end of file diff --git a/version.h b/version.h index 97b5594..b61ab1a 100644 --- a/version.h +++ b/version.h @@ -1,8 +1,8 @@ -/* Dire Wolf version 1.3 */ +/* Dire Wolf version 1.4 */ #define APP_TOCALL "APDW" #define MAJOR_VERSION 1 -#define MINOR_VERSION 3 +#define MINOR_VERSION 4 //#define EXTRA_VERSION "Beta Test" diff --git a/waypoint.c b/waypoint.c new file mode 100644 index 0000000..4025b9c --- /dev/null +++ b/waypoint.c @@ -0,0 +1,624 @@ +// +// This file is part of Dire Wolf, an amateur radio packet TNC. +// +// Copyright (C) 2014, 2015, 2016 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 +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + + +//#define DEBUG 1 + + +/*------------------------------------------------------------------ + * + * Module: waypoint.c + * + * Purpose: Send NMEA waypoint sentences to GPS display or mapping application. + * + *---------------------------------------------------------------*/ + +#include +#include + +#if __WIN32__ +#include +#include +#else +#define __USE_XOPEN2KXSI 1 +#define __USE_XOPEN 1 +//#define __USE_POSIX 1 +#include +#include +#include +#endif + +#include +#include +#include + +#include "direwolf.h" +#include "config.h" +#include "textcolor.h" +#include "latlong.h" +#include "waypoint.h" +#include "grm_sym.h" /* Garmin symbols */ +#include "mgn_icon.h" /* Magellan icons */ +#include "dwgpsnmea.h" +#include "serial_port.h" + + +static MYFDTYPE s_waypoint_port_fd = MYFDERROR; + +static int s_waypoint_formats = 0; /* which formats should we generate? */ + +static int s_waypoint_debug = 0; /* Print information flowing to attached device. */ + + + +static void append_checksum (char *sentence); +static void send_sentence (char *sent); + + + +void waypoint_set_debug (int n) +{ + s_waypoint_debug = n; +} + + +/*------------------------------------------------------------------- + * + * Name: waypoint_init + * + * Purpose: Initialization for waypoint output port. + * + * Inputs: mc - Pointer to configuration options. + * + * ->waypoint_port - Name of serial port. COM1, /dev/ttyS0, etc. + * + * + * (currently none) - speed, baud. Default 4800 if not set + * + * + * ->waypoint_formats - Set of formats enabled. + * If none set, default to generic & Kenwood. + * + * Global output: s_waypoint_port_fd + * + * Description: First to see if this is shared with GPS input. + * If not, open serial port. + * + * Restriction: MUST be done after GPS init because we might be sharing the + * same serial port device. + * + *---------------------------------------------------------------*/ + + +void waypoint_init (struct misc_config_s *mc) +{ + +#if DEBUG + text_color_set (DW_COLOR_DEBUG); + dw_printf ("waypoint_init() device=%s formats=%d\n", mc->waypoint_port, mc->waypoint_formats); +#endif + +/* + * TODO: + * Are we sharing with GPS input? + * First try to get fd if they have same device name. + * If that fails, do own serial port open. + */ + if (strlen(mc->waypoint_port) > 0) { + + s_waypoint_port_fd = dwgpsnmea_get_fd (mc->waypoint_port, 4800); + + if (s_waypoint_port_fd == MYFDERROR) { + s_waypoint_port_fd = serial_port_open (mc->waypoint_port, 4800); + } + else { + text_color_set (DW_COLOR_INFO); + dw_printf ("Note: Sharing same port for GPS input and waypoint output.\n"); + } + + if (s_waypoint_port_fd == MYFDERROR) { + text_color_set (DW_COLOR_ERROR); + dw_printf ("Unable to open %s for waypoint output.\n", mc->waypoint_port); + return; + } + + s_waypoint_formats = mc->waypoint_formats; + if (s_waypoint_formats == 0) { + s_waypoint_formats = WPT_FORMAT_NMEA_GENERIC | WPT_FORMAT_KENWOOD; + } + if (s_waypoint_formats & WPT_FORMAT_GARMIN) { + s_waypoint_formats |= WPT_FORMAT_NMEA_GENERIC; /* See explanation below. */ + } + } + + +#if DEBUG + text_color_set (DW_COLOR_DEBUG); + dw_printf ("end of waypoint_init: s_waypoint_port_fd = %d\n", s_waypoint_port_fd); +#endif +} + + + +/*------------------------------------------------------------------- + * + * Name: append_checksum + * + * Purpose: Append checksum to the sentence. + * + * In/out: sentence - NMEA sentence beginning with '$'. + * + * Description: Checksum is exclusive of characters except leading '$'. + * We append '*' and an upper case two hexadecimal value. + * + * Don't add CR/LF at this point. + * + *--------------------------------------------------------------------*/ + +static void append_checksum (char *sentence) +{ + char *p; + int cs; + + assert (sentence[0] == '$'); + + cs = 0; + for (p = sentence+1; *p != '\0'; p++) { + cs ^= *p; + } + + sprintf (p, "*%02X", cs & 0xff); + +} /* end append_checksum */ + + + +/*------------------------------------------------------------------- + * + * Name: nema_send_waypoint + * + * Purpose: Convert APRS position or object into NMEA waypoint sentence + * for use by a GPS display or other mapping application. + * + * Inputs: wname_in - Name of waypoint. Max of 9 characters. + * dlat - Latitude. + * dlong - Longitude. + * symtab - Symbol table or overlay character. + * symbol - Symbol code. + * alt - Altitude in meters or G_UNKNOWN. + * course - Course in degrees or G_UNKNOWN for unknown. + * speed - Speed in knots or G_UNKNOWN. + * comment_in - Description or message. + * + * + * Description: Currently we send multiple styles. Maybe someday there might + * be an option to send a selected subset. + * + * $GPWPL - NMEA generic with only location and name. + * $PGRMW - Garmin, adds altitude, symbol, and comment + * to previously named waypoint. + * $PMGNWPL - Magellan, more complete for stationary objects. + * $PKWDWPL - Kenwood with APRS style symbol but missing comment. + * +* + * AvMap G5 notes: + * + * https://sites.google.com/site/kd7kuj/home/files?pli=1 + * https://sites.google.com/site/kd7kuj/home/files/AvMapMessaging040810.pdf?attredirects=0&d=1 + * + * It sends $GPGGA & $GPRMC with location. + * It understands generic $GPWPL and Kenwood $PKWDWPL. + * + * There are some proprietary $PAVP* used only for messaging. + * Messaging would be a separate project. + * + *--------------------------------------------------------------------*/ + + +void waypoint_send_sentence (char *name_in, double dlat, double dlong, char symtab, char symbol, + float alt, float course, float speed, char *comment_in) +{ + char wname[12]; /* Waypoint name. Any , or * removed. */ + char slat[12]; /* DDMM.mmmm */ + char slat_ns[2]; /* N or S */ + char slong[12]; /* DDDMM.mmmm */ + char slong_ew[2]; /* E or W */ + char wcomment[256]; /* Comment. Any , or * removed. */ + char salt[12]; /* altitude as string, empty if unknown */ + char sspeed[12]; /* speed as string, empty if unknown */ + char scourse[12]; /* course as string, empty if unknown */ + char *p; + + char sentence[500]; + +#if DEBUG + text_color_set (DW_COLOR_DEBUG); + dw_printf ("waypoint_send_sentence (\"%s\", \"%c%c\")\n", name_in, symtab, symbol); +#endif + + +/* + * We need to remove any , or * from name, symbol, or comment because they are field delimiters. + * Follow precedent of Geosat AvMap $PAVPMSG sentence and make the following substitutions: + * + * , -> | + * * -> ~ + * + * The system on the other end would need to change them back after extracting the + * fields delimited by , or *. + * We will deal with the symbol in the Kenwood section. + * Needs to be left intact for other icon/symbol conversions. + */ + + strlcpy (wname, name_in, sizeof(wname)); + for (p=wname; *p != '\0'; p++) { + if (*p == ',') *p = '|'; + if (*p == '*') *p = '~'; + } + + strlcpy (wcomment, comment_in, sizeof(wcomment)); + for (p=wcomment; *p != '\0'; p++) { + if (*p == ',') *p = '|'; + if (*p == '*') *p = '~'; + } + + +/* + * Convert numeric values to character form. + * G_UNKNOWN value will result in an empty string. + */ + + latitude_to_nmea (dlat, slat, slat_ns); + longitude_to_nmea (dlong, slong, slong_ew); + + + if (alt == G_UNKNOWN) { + strcpy (salt, ""); + } + else { + snprintf (salt, sizeof(salt), "%.1f", alt); + } + + if (speed == G_UNKNOWN) { + strcpy (sspeed, ""); + } + else { + snprintf (sspeed, sizeof(sspeed), "%.1f", speed); + } + + if (course == G_UNKNOWN) { + strcpy (scourse, ""); + } + else { + snprintf (scourse, sizeof(scourse), "%.1f", course); + } + + +/* + * NMEA Generic. + * + * Has only location and name. Rather disappointing. + * + * $GPWPL,ddmm.mmmm,ns,dddmm.mmmm,ew,wname*99 + * + * Where, + * ddmm.mmmm,ns is latitude + * dddmm.mmmm,ew is longitude + * wname is the waypoint name + * *99 is checksum + */ + + if (s_waypoint_formats & WPT_FORMAT_NMEA_GENERIC) { + + snprintf (sentence, sizeof(sentence), "$GPWPL,%s,%s,%s,%s,%s", slat, slat_ns, slong, slong_ew, wname); + append_checksum (sentence); + send_sentence (sentence); + } + + +/* + * Garmin + * + * https://www8.garmin.com/support/pdf/NMEA_0183.pdf + * + * No location! Adds altitude, symbol, and comment to existing waypoint. + * So, we should always send the NMEA generic waypoint before this one. + * The init function should take care of that. + * + * $PGRMW,wname,alt,symbol,comment*99 + * + * Where, + * + * wname is waypoint name. Must match existing waypoint. + * alt is altitude in meters. + * symbol is symbol code. Hexadecimal up to FFFF. + * See Garmin Device Interface Specification + * 001-0063-00 for values of "symbol_type." + * comment is comment for the waypoint. + * *99 is checksum + */ + + if (s_waypoint_formats & WPT_FORMAT_GARMIN) { + + int i = symbol - ' '; + int grm_sym; /* Garmin symbol code. */ + + if (i >= 0 && i < SYMTAB_SIZE) { + if (symtab == '/') { + grm_sym = grm_primary_symtab[i]; + } + else { + grm_sym = grm_alternate_symtab[i]; + } + } + else { + grm_sym = sym_default; + } + + snprintf (sentence, sizeof(sentence), "$PGRMW,%s,%s,%04X,%s", wname, salt, grm_sym, wcomment); + append_checksum (sentence); + send_sentence (sentence); + } + + +/* + * Magellan + * + * http://www.gpsinformation.org/mag-proto-2-11.pdf Rev 2.11, Mar 2003, P/N 21-00091-000 + * http://gpsinformation.net/mag-proto.htm Rev 1.0, Aug 1999, P/N 21-00091-000 + * + * + * $PMGNWPL,ddmm.mmmm,ns,dddmm.mmmm,ew,alt,unit,wname,comment,icon,xx*99 + * + * Where, + * ddmm.mmmm,ns is latitude + * dddmm.mmmm,ew is longitude + * alt is altitude + * unit is M for meters or F for feet + * wname is the waypoint name + * comment is message or comment + * icon is one or two letters for icon code + * xx is waypoint type which is optional, not well + * defined, and not used in their example + * so we won't use it. + * *99 is checksum + * + * Possible enhancement: If the "object report" has the kill option set, use $PMGNDWP + * to delete that specific waypoint. + */ + + if (s_waypoint_formats & WPT_FORMAT_MAGELLAN) { + + int i = symbol - ' '; + char sicon[3]; /* Magellan icon string. Currently 1 or 2 characters. */ + + if (i >= 0 && i < SYMTAB_SIZE) { + if (symtab == '/') { + strlcpy (sicon, mgn_primary_symtab[i], sizeof(sicon)); + } + else { + strlcpy (sicon, mgn_alternate_symtab[i], sizeof(sicon)); + } + } + else { + strlcpy (sicon, MGN_default, sizeof(sicon)); + } + + snprintf (sentence, sizeof(sentence), "$PMGNWPL,%s,%s,%s,%s,%s,M,%s,%s,%s", + slat, slat_ns, slong, slong_ew, salt, wname, wcomment, sicon); + append_checksum (sentence); + send_sentence (sentence); + } + + +/* + * Kenwood + * + * + * $PKWDWPL,hhmmss,v,ddmm.mm,ns,dddmm.mm,ew,speed,course,ddmmyy,alt,wname,ts*99 + * + * Where, + * hhmmss is time in UTC from the clock in the transceiver. + * + * This will be bogus if the clock was not set properly. + * It does not use the timestamp from a position + * report which could be useful. + * + * GPS Status A = active, V = void. + * It looks like this might be modeled after the GPS status values + * we see in $GPRMC. i.e. Does the transceiver know its location? + * I dont see how that information would be relevant in this context. + * I've observed this under various conditions (No GPS, GPS with/without + * fix) and it has always been "V." + * (There is some information out there indicating this field + * can contain "I" for invalid but I don't think that is accurate.) + * + * ddmm.mm,ns is latitude. N or S. + * dddmm.mm,ew is longitude. E or W. + * + * The D710 produces two fractional digits for minutes. + * This is the same resolution most often used + * in APRS packets. Any additional resolution offered by + * the compressed format or the DAO option is not conveyed here. + * We will provide greater resolution. + * + * speed is speed over ground, knots. + * course is course over ground, degrees. + * + * Empty if not available. + * + * ddmmyy is date. See comments for time. + * + * alt is altitude, meters above mean sea level. + * + * Empty if no altitude is available. + * + * wname is the waypoint name. For an Object Report, the id is the object name. + * For a position report, it is the call of the sending station. + * + * An Object name can contain any printable characters. + * What if object name contains , or * characters? + * Those are field delimiter characters and it would be unfortunate + * if they appeared in a NMEA sentence data field. + * + * If there is a comma in the name, such as "test,5" the D710A displays + * it fine but we end up with an extra field. + * + * $PKWDWPL,150803,V,4237.14,N,07120.83,W,,,190316,,test,5,/'*30 + * + * If the name contains an asterisk, it doesn't show up on the + * display and no waypoint sentence is generated. + * We will substitute these two characters following the AvMap precedent. + * + * $PKWDWPL,204714,V,4237.1400,N,07120.8300,W,,,200316,,test|5,/'*61 + * $PKWDWPL,204719,V,4237.1400,N,07120.8300,W,,,200316,,test~6,/'*6D + * + * ts are the table and symbol. + * + * What happens if the symbol is comma or asterisk? + * , Boy Scouts / Girl Scouts + * * SnowMobile / Snow + * + * the D710A just pushes them thru without checking. + * These would not be parsed properly: + * + * $PKWDWPL,150753,V,4237.14,N,07120.83,W,,,190316,,test3,/,*1B + * $PKWDWPL,150758,V,4237.14,N,07120.83,W,,,190316,,test4,/**3B + * + * We perform the usual substitution and the other end would + * need to change them back after extracting from NMEA sentence. + * + * $PKWDWPL,204704,V,4237.1400,N,07120.8300,W,,,200316,,test3,/|*41 + * $PKWDWPL,204709,V,4237.1400,N,07120.8300,W,,,200316,,test4,/~*49 + * + * + * *99 is checksum + * + * Oddly, there is no place for comment. + */ + + + + if (s_waypoint_formats & WPT_FORMAT_KENWOOD) { + + time_t now; + struct tm tm; + char stime[8]; + char sdate[8]; + char ken_sym; /* APRS symbol with , or * substituted. */ + + now = time(NULL); + gmtime_r (&now, &tm); + strftime (stime, sizeof(stime), "%H%M%S", &tm); + strftime (sdate, sizeof(sdate), "%d%m%y", &tm); + + // A symbol code of , or * would not be good because + // they are field delimiters for NMEA sentences. + + // The AvMap G5 to Kenwood protocol description performs a substitution + // for these characters that appear in message text. + // , -> | + // * -> ~ + + // Those two are listed as "TNC Stream Switch" and are not used for symbols. + // It might be reasonable assumption that this same substitution might be + // used for the symbol code. + + if (symbol == ',') ken_sym = '|'; + else if (symbol == '*') ken_sym = '~'; + else ken_sym = symbol; + + snprintf (sentence, sizeof(sentence), "$PKWDWPL,%s,V,%s,%s,%s,%s,%s,%s,%s,%s,%s,%c%c", + stime, slat, slat_ns, slong, slong_ew, + sspeed, scourse, sdate, salt, wname, symtab, ken_sym); + append_checksum (sentence); + send_sentence (sentence); + } + + +/* + * One application recognizes these. Not implemented at this time. + * + * $GPTLL,01,ddmm.mmmm,ns,dddmm.mmmm,ew,tname,000000.00,T,R*99 + * + * Where, + * ddmm.mmmm,ns is latitude + * dddmm.mmmm,ew is longitude + * tname is the target name + * 000000.00 is timestamp ??? + * T is target status (S for need help) + * R is reference target ??? + * *99 is checksum + * + * + * $GPTXT,01,01,tname,message*99 + * + * Where, + * + * 01 is total number of messages in transmission + * 01 is message number in this transmission + * tname is target name. Should match name in WPL or TTL. + * message is the message. + * *99 is checksum + * + */ + + +} /* end waypoint_send_sentence */ + + +/* + * Append CR LF and send it. + */ + +static void send_sentence (char *sent) +{ + + char final[256]; + + + if (s_waypoint_port_fd == MYFDERROR) { + return; + } + + if (s_waypoint_debug) { + text_color_set(DW_COLOR_XMIT); + dw_printf ("%s\n", sent); + } + + strlcpy (final, sent, sizeof(final)); + strlcat (final, "\r\n", sizeof(final)); + + serial_port_write (s_waypoint_port_fd, final, strlen(final)); + +} /* send_sentence */ + + + +void waypoint_term () +{ + + if (s_waypoint_port_fd != MYFDERROR) { + //serial_port_close (s_waypoint_port_fd); + s_waypoint_port_fd = MYFDERROR; + } +} + + +/* end waypoint.c */ diff --git a/waypoint.h b/waypoint.h new file mode 100644 index 0000000..0f5ef3a --- /dev/null +++ b/waypoint.h @@ -0,0 +1,22 @@ + +/* + * Name: waypoint.h + */ + + +#include "ax25_pad.h" /* for packet_t */ + +#include "config.h" /* for struct misc_config_s */ + + +void waypoint_init (struct misc_config_s *misc_config); + +void waypoint_set_debug (int n); + +void waypoint_send_sentence (char *wname_in, double dlat, double dlong, char symtab, char symbol, + float alt, float course, float speed, char *comment_in); + +void waypoint_term (); + + +/* end waypoint.h */