1
0
Fork 0

Add support for GPSD.

ycs232-kbc
Jonathan Naylor 4 years ago
parent 7759575bbb
commit aa0ba6ec46

@ -17,8 +17,8 @@
*/ */
#include "APRSWriter.h" #include "APRSWriter.h"
#include "YSFDefines.h" #include "YSFDefines.h"
#include "Log.h"
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
@ -37,10 +37,13 @@ m_desc(),
m_suffix(suffix), m_suffix(suffix),
m_aprsAddress(), m_aprsAddress(),
m_aprsPort(port), m_aprsPort(port),
m_aprsSocket(), m_aprsSocket()
m_mobileGPSAddress(), #if !defined(_WIN32) && !defined(_WIN64)
m_mobileGPSPort(0U), ,m_gpsdEnabled(false),
m_mobileSocket(NULL) m_gpsdAddress(),
m_gpsdPort(0U),
m_gpsdData()
#endif
{ {
assert(!callsign.empty()); assert(!callsign.empty());
assert(!address.empty()); assert(!address.empty());
@ -72,33 +75,38 @@ void CAPRSWriter::setStaticLocation(float latitude, float longitude, int height)
m_height = 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(!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() bool CAPRSWriter::open()
{ {
if (m_mobileSocket != NULL) { #if !defined(_WIN32) && !defined(_WIN64)
bool ret = m_mobileSocket->open(); if (m_gpsdEnabled) {
if (!ret) { int ret = ::gps_open(m_gpsdAddress.c_str(), m_gpsdPort.c_str(), &m_gpsdData);
delete m_mobileSocket; if (ret != 0) {
m_mobileSocket = NULL; LogError("Error when opening access to gpsd - %d - %s", errno, ::gps_errstr(errno));
return false; return false;
} }
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL);
// Poll the GPS every minute // Poll the GPS every minute
m_idTimer.setTimeout(60U); m_idTimer.setTimeout(60U);
} else { } else {
m_idTimer.setTimeout(20U * 60U); m_idTimer.setTimeout(20U * 60U);
} }
#else
m_idTimer.setTimeout(20U * 60U);
#endif
m_idTimer.start(); m_idTimer.start();
return m_aprsSocket.open(); return m_aprsSocket.open();
@ -169,36 +177,34 @@ void CAPRSWriter::clock(unsigned int ms)
{ {
m_idTimer.clock(ms); m_idTimer.clock(ms);
if (m_mobileSocket != NULL) { #if !defined(_WIN32) && !defined(_WIN64)
if (m_gpsdEnabled) {
if (m_idTimer.hasExpired()) { if (m_idTimer.hasExpired()) {
pollGPS(); sendIdFrameMobile();
m_idTimer.start(); m_idTimer.start();
} }
sendIdFrameMobile();
} else { } else {
#endif
if (m_idTimer.hasExpired()) { if (m_idTimer.hasExpired()) {
sendIdFrameFixed(); sendIdFrameFixed();
m_idTimer.start(); m_idTimer.start();
} }
#if !defined(_WIN32) && !defined(_WIN64)
} }
#endif
} }
void CAPRSWriter::close() void CAPRSWriter::close()
{ {
m_aprsSocket.close(); m_aprsSocket.close();
if (m_mobileSocket != NULL) { #if !defined(_WIN32) && !defined(_WIN64)
m_mobileSocket->close(); if (m_gpsdEnabled) {
delete m_mobileSocket; ::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL);
::gps_close(&m_gpsdData);
} }
} #endif
bool CAPRSWriter::pollGPS()
{
assert(m_mobileSocket != NULL);
return m_mobileSocket->write((unsigned char*)"YSFGateway", 10U, m_mobileGPSAddress, m_mobileGPSPort);
} }
void CAPRSWriter::sendIdFrameFixed() void CAPRSWriter::sendIdFrameFixed()
@ -264,29 +270,25 @@ void CAPRSWriter::sendIdFrameFixed()
void CAPRSWriter::sendIdFrameMobile() void CAPRSWriter::sendIdFrameMobile()
{ {
// Grab GPS data if it's available if (!m_gpsdEnabled)
unsigned char buffer[200U];
in_addr address;
unsigned int port;
int ret = m_mobileSocket->read(buffer, 200U, address, port);
if (ret <= 0)
return; return;
buffer[ret] = '\0'; if (!::gps_waiting(&m_gpsdData, 0))
return;
// Parse the GPS data bool latlonSet = (m_gpsdData.set & LATLON_SET) == LATLON_SET;
char* pLatitude = ::strtok((char*)buffer, ",\n"); // Latitude bool altitudeSet = (m_gpsdData.set & ALTITUDE_SET) == ALTITUDE_SET;
char* pLongitude = ::strtok(NULL, ",\n"); // Longitude bool velocitySet = (m_gpsdData.set & SPEED_SET) == SPEED_SET;
char* pAltitude = ::strtok(NULL, ",\n"); // Altitude (m) bool bearingSet = (m_gpsdData.set & TRACK_SET) == TRACK_SET;
char* pVelocity = ::strtok(NULL, ",\n"); // Velocity (kms/h)
char* pBearing = ::strtok(NULL, "\n"); // Bearing
if (pLatitude == NULL || pLongitude == NULL || pAltitude == NULL) if (!latlonSet)
return; return;
float rawLatitude = float(::atof(pLatitude)); float rawLatitude = float(m_gpsdData.fix.latitude);
float rawLongitude = float(::atof(pLongitude)); float rawLongitude = float(m_gpsdData.fix.longitude);
float rawAltitude = float(::atof(pAltitude)); float rawAltitude = float(m_gpsdData.fix.altMSL);
float rawVelocity = float(m_gpsdData.fix.speed);
float rawBearing = float(m_gpsdData.fix.track);
char desc[200U]; char desc[200U];
if (m_txFrequency != 0U) { if (m_txFrequency != 0U) {
@ -339,14 +341,14 @@ void CAPRSWriter::sendIdFrameMobile()
lat, (rawLatitude < 0.0F) ? 'S' : 'N', lat, (rawLatitude < 0.0F) ? 'S' : 'N',
lon, (rawLongitude < 0.0F) ? 'W' : 'E'); lon, (rawLongitude < 0.0F) ? 'W' : 'E');
if (pBearing != NULL && pVelocity != NULL) { if (bearingSet && velocitySet)
float rawBearing = float(::atof(pBearing));
float rawVelocity = float(::atof(pVelocity));
::sprintf(output + ::strlen(output), "%03.0f/%03.0f", rawBearing, rawVelocity * 0.539957F); ::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);
m_aprsSocket.write((unsigned char*)output, (unsigned int)::strlen(output), m_aprsAddress, m_aprsPort); m_aprsSocket.write((unsigned char*)output, (unsigned int)::strlen(output), m_aprsAddress, m_aprsPort);
} }

@ -33,6 +33,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <gps.h>
#else #else
#include <winsock.h> #include <winsock.h>
#endif #endif
@ -48,7 +49,7 @@ public:
void setStaticLocation(float latitude, float longitude, int height); 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 unsigned char* source, const char* type, unsigned char radio, float latitude, float longitude); void write(const unsigned char* source, const char* type, unsigned char radio, float latitude, float longitude);
@ -69,11 +70,13 @@ private:
in_addr m_aprsAddress; in_addr m_aprsAddress;
unsigned int m_aprsPort; unsigned int m_aprsPort;
CUDPSocket m_aprsSocket; CUDPSocket m_aprsSocket;
in_addr m_mobileGPSAddress; #if !defined(_WIN32) && !defined(_WIN64)
unsigned int m_mobileGPSPort; bool m_gpsdEnabled;
CUDPSocket* m_mobileSocket; std::string m_gpsdAddress;
std::string m_gpsdPort;
struct gps_data_t m_gpsdData;
#endif
bool pollGPS();
void sendIdFrameFixed(); void sendIdFrameFixed();
void sendIdFrameMobile(); void sendIdFrameMobile();
}; };

@ -35,7 +35,7 @@ enum SECTION {
SECTION_NETWORK, SECTION_NETWORK,
SECTION_YSF_NETWORK, SECTION_YSF_NETWORK,
SECTION_FCS_NETWORK, SECTION_FCS_NETWORK,
SECTION_MOBILE_GPS, SECTION_GPSD,
SECTION_REMOTE_COMMANDS SECTION_REMOTE_COMMANDS
}; };
@ -87,9 +87,9 @@ m_ysfNetworkYSF2P25Port(0U),
m_fcsNetworkEnabled(false), m_fcsNetworkEnabled(false),
m_fcsNetworkFile(), m_fcsNetworkFile(),
m_fcsNetworkPort(0U), m_fcsNetworkPort(0U),
m_mobileGPSEnabled(false), m_gpsdEnabled(false),
m_mobileGPSAddress(), m_gpsdAddress(),
m_mobileGPSPort(0U), m_gpsdPort(),
m_remoteCommandsEnabled(false), m_remoteCommandsEnabled(false),
m_remoteCommandsPort(6073U) m_remoteCommandsPort(6073U)
{ {
@ -129,8 +129,8 @@ bool CConf::read()
section = SECTION_YSF_NETWORK; section = SECTION_YSF_NETWORK;
else if (::strncmp(buffer, "[FCS Network]", 13U) == 0) else if (::strncmp(buffer, "[FCS Network]", 13U) == 0)
section = SECTION_FCS_NETWORK; section = SECTION_FCS_NETWORK;
else if (::strncmp(buffer, "[Mobile GPS]", 12U) == 0) else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
section = SECTION_MOBILE_GPS; section = SECTION_GPSD;
else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0) else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0)
section = SECTION_REMOTE_COMMANDS; section = SECTION_REMOTE_COMMANDS;
else else
@ -249,13 +249,13 @@ bool CConf::read()
m_fcsNetworkFile = value; m_fcsNetworkFile = value;
else if (::strcmp(key, "Port") == 0) else if (::strcmp(key, "Port") == 0)
m_fcsNetworkPort = (unsigned int)::atoi(value); m_fcsNetworkPort = (unsigned int)::atoi(value);
} else if (section == SECTION_MOBILE_GPS) { } else if (section == SECTION_GPSD) {
if (::strcmp(key, "Enable") == 0) if (::strcmp(key, "Enable") == 0)
m_mobileGPSEnabled = ::atoi(value) == 1; m_gpsdEnabled = ::atoi(value) == 1;
else if (::strcmp(key, "Address") == 0) else if (::strcmp(key, "Address") == 0)
m_mobileGPSAddress = value; m_gpsdAddress = value;
else if (::strcmp(key, "Port") == 0) else if (::strcmp(key, "Port") == 0)
m_mobileGPSPort = (unsigned int)::atoi(value); m_gpsdPort = value;
} else if (section == SECTION_REMOTE_COMMANDS) { } else if (section == SECTION_REMOTE_COMMANDS) {
if (::strcmp(key, "Enable") == 0) if (::strcmp(key, "Enable") == 0)
m_remoteCommandsEnabled = ::atoi(value) == 1; m_remoteCommandsEnabled = ::atoi(value) == 1;
@ -500,19 +500,19 @@ unsigned int CConf::getFCSNetworkPort() const
return m_fcsNetworkPort; return m_fcsNetworkPort;
} }
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 bool CConf::getRemoteCommandsEnabled() const

@ -89,10 +89,10 @@ public:
std::string getFCSNetworkFile() const; std::string getFCSNetworkFile() const;
unsigned int getFCSNetworkPort() const; unsigned int getFCSNetworkPort() const;
// The Mobile GPS section // The GPSD section
bool getMobileGPSEnabled() const; bool getGPSDEnabled() const;
std::string getMobileGPSAddress() const; std::string getGPSDAddress() const;
unsigned int getMobileGPSPort() const; std::string getGPSDPort() const;
// The Remote Commands section // The Remote Commands section
bool getRemoteCommandsEnabled() const; bool getRemoteCommandsEnabled() const;
@ -153,9 +153,9 @@ private:
std::string m_fcsNetworkFile; std::string m_fcsNetworkFile;
unsigned int m_fcsNetworkPort; unsigned int m_fcsNetworkPort;
bool m_mobileGPSEnabled; bool m_gpsdEnabled;
std::string m_mobileGPSAddress; std::string m_gpsdAddress;
unsigned int m_mobileGPSPort; std::string m_gpsdPort;
bool m_remoteCommandsEnabled; bool m_remoteCommandsEnabled;
unsigned int m_remoteCommandsPort; unsigned int m_remoteCommandsPort;

@ -1,7 +1,7 @@
CC = gcc CC = gcc
CXX = g++ CXX = g++
CFLAGS = -g -O3 -Wall -std=c++0x -pthread CFLAGS = -g -O3 -Wall -std=c++0x -pthread
LIBS = -lm -lpthread LIBS = -lm -lpthread -lgps
LDFLAGS = -g LDFLAGS = -g
OBJECTS = APRSWriter.o Conf.o CRC.o DTMF.o FCSNetwork.o Golay24128.o GPS.o Log.o StopWatch.o Sync.o Thread.o Timer.o \ OBJECTS = APRSWriter.o Conf.o CRC.o DTMF.o FCSNetwork.o Golay24128.o GPS.o Log.o StopWatch.o Sync.o Thread.o Timer.o \

@ -1,20 +0,0 @@
CC = gcc
CXX = g++
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
LIBS = -lm -lpthread -lsocket
LDFLAGS = -g
OBJECTS = APRSWriter.o Conf.o CRC.o DTMF.o FCSNetwork.o Golay24128.o GPS.o Log.o StopWatch.o Sync.o Thread.o Timer.o \
UDPSocket.o Utils.o WiresX.o YSFConvolution.o YSFFICH.o YSFGateway.o YSFNetwork.o YSFPayload.o YSFReflectors.o
all: YSFGateway
YSFGateway: $(OBJECTS)
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o YSFGateway
%.o: %.cpp
$(CXX) $(CFLAGS) -c -o $@ $<
clean:
$(RM) YSFGateway *.o *.d *.bak *~

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

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

@ -61,10 +61,10 @@ Enable=1
Rooms=./FCSRooms.txt Rooms=./FCSRooms.txt
Port=42001 Port=42001
[Mobile GPS] [GPSD]
Enable=0 Enable=0
Address=127.0.0.1 Address=127.0.0.1
Port=7834 Port=2947
[Remote Commands] [Remote Commands]
Enable=0 Enable=0

Loading…
Cancel
Save