2015-09-07 23:56:20 +00:00
|
|
|
//
|
|
|
|
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
|
|
|
//
|
|
|
|
// Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
//#define DEBUG 1
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* Module: walk96.c
|
|
|
|
*
|
|
|
|
* Purpose: Quick hack to read GPS location and send very frequent
|
|
|
|
* position reports frames to a KISS TNC.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*---------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <string.h>
|
2015-11-08 01:57:02 +00:00
|
|
|
#include <math.h>
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
#include "direwolf.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "ax25_pad.h"
|
|
|
|
#include "textcolor.h"
|
|
|
|
#include "latlong.h"
|
2015-11-08 01:57:02 +00:00
|
|
|
#include "dwgps.h"
|
2015-09-07 23:56:20 +00:00
|
|
|
#include "encode_aprs.h"
|
|
|
|
#include "serial_port.h"
|
2015-11-08 01:57:02 +00:00
|
|
|
#include "kiss_frame.h"
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
#define MYCALL "WB2OSZ" /************ Change this if you use it!!! ***************/
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
#define HOWLONG 20 /* Run for 20 seconds then quit. */
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-09-07 23:56:20 +00:00
|
|
|
static MYFDTYPE tnc;
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
static void walk96 (int fix, double lat, double lon, float knots, float course, float alt);
|
|
|
|
|
|
|
|
|
2015-09-07 23:56:20 +00:00
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
int main (int argc, char *argv[])
|
2015-09-07 23:56:20 +00:00
|
|
|
{
|
|
|
|
struct misc_config_s config;
|
|
|
|
char cmd[100];
|
2015-11-08 01:57:02 +00:00
|
|
|
int debug_gps = 0;
|
|
|
|
int n;
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
// TD-D72A USB - Look for Silicon Labs CP210x.
|
2015-09-07 23:56:20 +00:00
|
|
|
// Just happens to be same on desktop & laptop.
|
|
|
|
|
|
|
|
tnc = serial_port_open ("COM5", 9600);
|
|
|
|
if (tnc == MYFDERROR) {
|
|
|
|
text_color_set (DW_COLOR_ERROR);
|
|
|
|
dw_printf ("Can't open serial port to KISS TNC.\n");
|
|
|
|
exit (EXIT_FAILURE); // defined in stdlib.h
|
|
|
|
}
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
strlcpy (cmd, "\r\rhbaud 9600\rkiss on\rrestart\r", sizeof(cmd));
|
2015-09-07 23:56:20 +00:00
|
|
|
serial_port_write (tnc, cmd, strlen(cmd));
|
2015-11-08 01:57:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
// USB GPS happens to be COM22
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
memset (&config, 0, sizeof(config));
|
2015-11-08 01:57:02 +00:00
|
|
|
strlcpy (config.gpsnmea_port, "COM22", sizeof(config.nmea_port));
|
|
|
|
|
|
|
|
dwgps_init (&config, debug_gps);
|
|
|
|
|
|
|
|
SLEEP_SEC(1); /* Wait for sample before reading. */
|
|
|
|
|
|
|
|
for (n=0; n<HOWLONG; n++) {
|
|
|
|
|
|
|
|
dwgps_info_t info;
|
|
|
|
dwfix_t fix;
|
|
|
|
|
|
|
|
fix = dwgps_read (&info);
|
|
|
|
|
|
|
|
if (fix > DWFIX_2D) {
|
|
|
|
walk96 (fix, info.dlat, info.dlon, info.speed_knots, info.track, info.altitude);
|
|
|
|
}
|
|
|
|
else if (fix < 0) {
|
|
|
|
text_color_set (DW_COLOR_ERROR);
|
|
|
|
dw_printf ("Can't communicate with GPS receiver.\n");
|
|
|
|
exit (EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
text_color_set (DW_COLOR_ERROR);
|
|
|
|
dw_printf ("GPS fix not available.\n");
|
|
|
|
}
|
|
|
|
SLEEP_SEC(1);
|
|
|
|
}
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Exit out of KISS mode.
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
serial_port_write (tnc, "\xc0\xff\xc0", 3);
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
SLEEP_MS(100);
|
2015-11-08 01:57:02 +00:00
|
|
|
exit (EXIT_SUCCESS);
|
2015-09-07 23:56:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Should be called once per second. */
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
static void walk96 (int fix, double lat, double lon, float knots, float course, float alt)
|
2015-09-07 23:56:20 +00:00
|
|
|
{
|
|
|
|
static int sequence = 0;
|
|
|
|
char comment[50];
|
|
|
|
|
|
|
|
sequence++;
|
2015-11-08 01:57:02 +00:00
|
|
|
snprintf (comment, sizeof(comment), "Sequence number %04d", sequence);
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Construct the packet in normal monitoring format.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int messaging = 0;
|
|
|
|
int compressed = 0;
|
|
|
|
|
|
|
|
char info[AX25_MAX_INFO_LEN];
|
|
|
|
int info_len;
|
|
|
|
|
|
|
|
char position_report[AX25_MAX_PACKET_LEN];
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
|
|
|
|
// TODO (high, bug): Why do we see !4237.13N/07120.84W=PHG0000... when all values set to unknown.
|
|
|
|
|
|
|
|
|
2015-09-07 23:56:20 +00:00
|
|
|
info_len = encode_position (messaging, compressed,
|
|
|
|
lat, lon, (int)(DW_METERS_TO_FEET(alt)),
|
2015-11-08 01:57:02 +00:00
|
|
|
'/', '=',
|
|
|
|
G_UNKNOWN, G_UNKNOWN, G_UNKNOWN, "", // PHGd
|
|
|
|
(int)roundf(course), (int)roundf(knots),
|
2015-09-07 23:56:20 +00:00
|
|
|
445.925, 0, 0,
|
|
|
|
comment,
|
|
|
|
info, sizeof(info));
|
|
|
|
|
2015-11-08 01:57:02 +00:00
|
|
|
snprintf (position_report, sizeof(position_report), "%s>WALK96:%s", MYCALL, info);
|
2015-09-07 23:56:20 +00:00
|
|
|
|
|
|
|
text_color_set (DW_COLOR_XMIT);
|
|
|
|
dw_printf ("%s\n", position_report);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert it into AX.25 frame.
|
|
|
|
*/
|
|
|
|
packet_t pp;
|
|
|
|
unsigned char ax25_frame[AX25_MAX_PACKET_LEN];
|
|
|
|
int frame_len;
|
|
|
|
|
|
|
|
pp = ax25_from_text (position_report, 1);
|
|
|
|
|
|
|
|
if (pp == NULL) {
|
|
|
|
text_color_set (DW_COLOR_ERROR);
|
|
|
|
dw_printf ("Unexpected error in ax25_from_text. Quitting.\n");
|
|
|
|
exit (EXIT_FAILURE); // defined in stdlib.h
|
|
|
|
}
|
|
|
|
|
|
|
|
ax25_frame[0] = 0; // Insert channel before KISS encapsulation.
|
|
|
|
|
|
|
|
frame_len = ax25_pack (pp, ax25_frame+1);
|
|
|
|
ax25_delete (pp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Encapsulate as KISS and send to TNC.
|
|
|
|
*/
|
|
|
|
|
|
|
|
unsigned char kiss_frame[AX25_MAX_PACKET_LEN*2];
|
|
|
|
int kiss_len;
|
|
|
|
|
|
|
|
kiss_len = kiss_encapsulate (ax25_frame, frame_len+1, (unsigned char *)kiss_frame);
|
|
|
|
|
|
|
|
//text_color_set (DW_COLOR_DEBUG);
|
|
|
|
//dw_printf ("AX.25 frame length = %d, KISS frame length = %d\n", frame_len, kiss_len);
|
|
|
|
|
|
|
|
//kiss_debug_print (1, NULL, kiss_frame, kiss_len);
|
|
|
|
|
|
|
|
serial_port_write (tnc, kiss_frame, kiss_len);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* end walk96.c */
|