Use gpsd instead of MobileGPS.

This commit is contained in:
Jonathan Naylor 2020-06-03 12:24:29 +01:00
parent dfa50edd03
commit 61479b55dc
8 changed files with 107 additions and 102 deletions

View File

@ -17,6 +17,7 @@
*/
#include "APRSWriter.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
@ -35,10 +36,13 @@ m_height(0),
m_desc(),
m_aprsAddress(),
m_aprsPort(port),
m_aprsSocket(),
m_mobileGPSAddress(),
m_mobileGPSPort(0U),
m_mobileSocket(NULL)
m_aprsSocket()
#if !defined(_WIN32) && !defined(_WIN64)
,m_gpsdEnabled(false),
m_gpsdAddress(),
m_gpsdPort(0U),
m_gpsdData()
#endif
{
assert(!callsign.empty());
assert(!address.empty());
@ -70,32 +74,36 @@ void CAPRSWriter::setStaticLocation(float latitude, float longitude, int height)
m_height = height;
}
void CAPRSWriter::setMobileLocation(const std::string& address, unsigned int port)
void CAPRSWriter::setGPSDLocation(const std::string& address, const std::string& port)
{
#if !defined(_WIN32) && !defined(_WIN64)
assert(!address.empty());
assert(port > 0U);
assert(!port.empty());
m_mobileGPSAddress = CUDPSocket::lookup(address);
m_mobileGPSPort = port;
m_mobileSocket = new CUDPSocket;
m_gpsdEnabled = true;
m_gpsdAddress = address;
m_gpsdPort = port;
#endif
}
bool CAPRSWriter::open()
{
if (m_mobileSocket != NULL) {
bool ret = m_mobileSocket->open();
if (!ret) {
delete m_mobileSocket;
m_mobileSocket = NULL;
#if !defined(_WIN32) && !defined(_WIN64)
if (m_gpsdEnabled) {
int ret = ::gps_open(m_gpsdAddress.c_str(), m_gpsdPort.c_str(), &m_gpsdData);
if (ret != 0) {
LogError("Error when opening access to gpsd - %d - %s", errno, ::gps_errstr(errno));
return false;
}
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL);
// Poll the GPS every minute
m_idTimer.setTimeout(60U);
} else {
m_idTimer.setTimeout(20U * 60U);
}
#endif
m_idTimer.start();
@ -113,36 +121,34 @@ void CAPRSWriter::clock(unsigned int ms)
{
m_idTimer.clock(ms);
if (m_mobileSocket != NULL) {
#if !defined(_WIN32) && !defined(_WIN64)
if (m_gpsdEnabled) {
if (m_idTimer.hasExpired()) {
pollGPS();
sendIdFrameMobile();
m_idTimer.start();
}
sendIdFrameMobile();
} else {
#endif
if (m_idTimer.hasExpired()) {
sendIdFrameFixed();
m_idTimer.start();
}
#if !defined(_WIN32) && !defined(_WIN64)
}
#endif
}
void CAPRSWriter::close()
{
m_aprsSocket.close();
if (m_mobileSocket != NULL) {
m_mobileSocket->close();
delete m_mobileSocket;
#if !defined(_WIN32) && !defined(_WIN64)
if (m_gpsdEnabled) {
::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL);
::gps_close(&m_gpsdData);
}
}
bool CAPRSWriter::pollGPS()
{
assert(m_mobileSocket != NULL);
return m_mobileSocket->write((unsigned char*)"NXDNGateway", 11U, m_mobileGPSAddress, m_mobileGPSPort);
#endif
}
void CAPRSWriter::sendIdFrameFixed()
@ -208,29 +214,25 @@ void CAPRSWriter::sendIdFrameFixed()
void CAPRSWriter::sendIdFrameMobile()
{
// Grab GPS data if it's available
unsigned char buffer[200U];
in_addr address;
unsigned int port;
int ret = m_mobileSocket->read(buffer, 200U, address, port);
if (ret <= 0)
if (!m_gpsdEnabled)
return;
buffer[ret] = '\0';
// Parse the GPS data
char* pLatitude = ::strtok((char*)buffer, ",\n"); // Latitude
char* pLongitude = ::strtok(NULL, ",\n"); // Longitude
char* pAltitude = ::strtok(NULL, ",\n"); // Altitude (m)
char* pVelocity = ::strtok(NULL, ",\n"); // Velocity (kms/h)
char* pBearing = ::strtok(NULL, "\n"); // Bearing
if (pLatitude == NULL || pLongitude == NULL || pAltitude == NULL)
if (!::gps_waiting(&m_gpsdData, 0))
return;
float rawLatitude = float(::atof(pLatitude));
float rawLongitude = float(::atof(pLongitude));
float rawAltitude = float(::atof(pAltitude));
bool latlonSet = (m_gpsdData.set & LATLON_SET) == LATLON_SET;
bool altitudeSet = (m_gpsdData.set & ALTITUDE_SET) == ALTITUDE_SET;
bool velocitySet = (m_gpsdData.set & SPEED_SET) == SPEED_SET;
bool bearingSet = (m_gpsdData.set & TRACK_SET) == TRACK_SET;
if (!latlonSet)
return;
float rawLatitude = float(m_gpsdData.fix.latitude);
float rawLongitude = float(m_gpsdData.fix.longitude);
float rawAltitude = float(m_gpsdData.fix.altMSL);
float rawVelocity = float(m_gpsdData.fix.speed);
float rawBearing = float(m_gpsdData.fix.track);
char desc[200U];
if (m_txFrequency != 0U) {
@ -283,14 +285,14 @@ void CAPRSWriter::sendIdFrameMobile()
lat, (rawLatitude < 0.0F) ? 'S' : 'N',
lon, (rawLongitude < 0.0F) ? 'W' : 'E');
if (pBearing != NULL && pVelocity != NULL) {
float rawBearing = float(::atof(pBearing));
float rawVelocity = float(::atof(pVelocity));
if (bearingSet && velocitySet)
::sprintf(output + ::strlen(output), "%03.0f/%03.0f", rawBearing, rawVelocity * 0.539957F);
}
::sprintf(output + ::strlen(output), "/A=%06.0f%s %s\r\n", float(rawAltitude) * 3.28F, band, desc);
if (altitudeSet)
::sprintf(output + ::strlen(output), "/A=%06.0f", float(rawAltitude) * 3.28F);
::sprintf(output + ::strlen(output), "%s %s\r\n", band, desc);
write(output);
}

View File

@ -33,6 +33,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <gps.h>
#else
#include <winsock.h>
#endif
@ -48,7 +49,7 @@ public:
void setStaticLocation(float latitude, float longitude, int height);
void setMobileLocation(const std::string& address, unsigned int port);
void setGPSDLocation(const std::string& address, const std::string& port);
void write(const char* data);
@ -57,23 +58,25 @@ public:
void close();
private:
bool m_enabled;
CTimer m_idTimer;
std::string m_callsign;
unsigned int m_txFrequency;
unsigned int m_rxFrequency;
float m_latitude;
float m_longitude;
int m_height;
std::string m_desc;
in_addr m_aprsAddress;
unsigned int m_aprsPort;
CUDPSocket m_aprsSocket;
in_addr m_mobileGPSAddress;
unsigned int m_mobileGPSPort;
CUDPSocket* m_mobileSocket;
bool m_enabled;
CTimer m_idTimer;
std::string m_callsign;
unsigned int m_txFrequency;
unsigned int m_rxFrequency;
float m_latitude;
float m_longitude;
int m_height;
std::string m_desc;
in_addr m_aprsAddress;
unsigned int m_aprsPort;
CUDPSocket m_aprsSocket;
#if !defined(_WIN32) && !defined(_WIN64)
bool m_gpsdEnabled;
std::string m_gpsdAddress;
std::string m_gpsdPort;
struct gps_data_t m_gpsdData;
#endif
bool pollGPS();
void sendIdFrameFixed();
void sendIdFrameMobile();
};

View File

@ -35,7 +35,7 @@ enum SECTION {
SECTION_LOG,
SECTION_APRS,
SECTION_NETWORK,
SECTION_MOBILE_GPS,
SECTION_GPSD,
SECTION_REMOTE_COMMANDS
};
@ -80,9 +80,9 @@ m_networkNXDN2DMRPort(0U),
m_networkStartup(9999U),
m_networkInactivityTimeout(0U),
m_networkDebug(false),
m_mobileGPSEnabled(false),
m_mobileGPSAddress(),
m_mobileGPSPort(0U),
m_gpsdEnabled(false),
m_gpsdAddress(),
m_gpsdPort(),
m_remoteCommandsEnabled(false),
m_remoteCommandsPort(6075U)
{
@ -122,8 +122,8 @@ bool CConf::read()
section = SECTION_APRS;
else if (::strncmp(buffer, "[Network]", 9U) == 0)
section = SECTION_NETWORK;
else if (::strncmp(buffer, "[Mobile GPS]", 12U) == 0)
section = SECTION_MOBILE_GPS;
else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
section = SECTION_GPSD;
else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0)
section = SECTION_REMOTE_COMMANDS;
else
@ -228,13 +228,13 @@ bool CConf::read()
m_networkInactivityTimeout = (unsigned int)::atoi(value);
else if (::strcmp(key, "Debug") == 0)
m_networkDebug = ::atoi(value) == 1;
} else if (section == SECTION_MOBILE_GPS) {
} else if (section == SECTION_GPSD) {
if (::strcmp(key, "Enable") == 0)
m_mobileGPSEnabled = ::atoi(value) == 1;
m_gpsdEnabled = ::atoi(value) == 1;
else if (::strcmp(key, "Address") == 0)
m_mobileGPSAddress = value;
m_gpsdAddress = value;
else if (::strcmp(key, "Port") == 0)
m_mobileGPSPort = (unsigned int)::atoi(value);
m_gpsdPort = value;
} else if (section == SECTION_REMOTE_COMMANDS) {
if (::strcmp(key, "Enable") == 0)
m_remoteCommandsEnabled = ::atoi(value) == 1;
@ -443,19 +443,19 @@ bool CConf::getNetworkDebug() const
return m_networkDebug;
}
bool CConf::getMobileGPSEnabled() const
bool CConf::getGPSDEnabled() const
{
return m_mobileGPSEnabled;
return m_gpsdEnabled;
}
std::string CConf::getMobileGPSAddress() const
std::string CConf::getGPSDAddress() const
{
return m_mobileGPSAddress;
return m_gpsdAddress;
}
unsigned int CConf::getMobileGPSPort() const
std::string CConf::getGPSDPort() const
{
return m_mobileGPSPort;
return m_gpsdPort;
}
bool CConf::getRemoteCommandsEnabled() const

View File

@ -83,10 +83,10 @@ public:
unsigned int getNetworkInactivityTimeout() const;
bool getNetworkDebug() const;
// The Mobile GPS section
bool getMobileGPSEnabled() const;
std::string getMobileGPSAddress() const;
unsigned int getMobileGPSPort() const;
// The GPSD section
bool getGPSDEnabled() const;
std::string getGPSDAddress() const;
std::string getGPSDPort() const;
// The Remote Commands section
bool getRemoteCommandsEnabled() const;
@ -140,9 +140,9 @@ private:
unsigned int m_networkInactivityTimeout;
bool m_networkDebug;
bool m_mobileGPSEnabled;
std::string m_mobileGPSAddress;
unsigned int m_mobileGPSPort;
bool m_gpsdEnabled;
std::string m_gpsdAddress;
std::string m_gpsdPort;
bool m_remoteCommandsEnabled;
unsigned int m_remoteCommandsPort;

View File

@ -1,11 +1,11 @@
CC = gcc
CXX = g++
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
LIBS = -lpthread
LIBS = -lpthread -lgps
LDFLAGS = -g
OBJECTS = APRSWriter.o Conf.o GPSHandler.o IcomNetwork.o KenwoodNetwork.o Log.o Mutex.o NXDNCRC.o NXDNGateway.o NXDNLookup.o NXDNNetwork.o \
Reflectors.o RptNetwork.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o
Reflectors.o RptNetwork.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o
all: NXDNGateway

View File

@ -603,12 +603,12 @@ void CNXDNGateway::createGPS()
m_writer->setInfo(txFrequency, rxFrequency, desc);
bool enabled = m_conf.getMobileGPSEnabled();
bool enabled = m_conf.getGPSDEnabled();
if (enabled) {
std::string address = m_conf.getMobileGPSAddress();
unsigned int port = m_conf.getMobileGPSPort();
std::string address = m_conf.getGPSDAddress();
std::string port = m_conf.getGPSDPort();
m_writer->setMobileLocation(address, port);
m_writer->setGPSDLocation(address, port);
} else {
float latitude = m_conf.getLatitude();
float longitude = m_conf.getLongitude();

View File

@ -62,10 +62,10 @@ Startup=10200
InactivityTimeout=10
Debug=0
[Mobile GPS]
[GPSD]
Enable=0
Address=127.0.0.1
Port=7834
Port=2947
[Remote Commands]
Enable=0

View File

@ -19,6 +19,6 @@
#if !defined(VERSION_H)
#define VERSION_H
const char* VERSION = "20200601";
const char* VERSION = "20200603";
#endif