diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index 0dc0177..a301eba 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -17,6 +17,7 @@ */ #include "APRSWriter.h" +#include "Log.h" #include #include @@ -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); } + diff --git a/NXDNGateway/APRSWriter.h b/NXDNGateway/APRSWriter.h index d486319..21f322f 100644 --- a/NXDNGateway/APRSWriter.h +++ b/NXDNGateway/APRSWriter.h @@ -33,6 +33,7 @@ #include #include #include +#include #else #include #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(); }; diff --git a/NXDNGateway/Conf.cpp b/NXDNGateway/Conf.cpp index 81e1af3..d1969b0 100644 --- a/NXDNGateway/Conf.cpp +++ b/NXDNGateway/Conf.cpp @@ -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 diff --git a/NXDNGateway/Conf.h b/NXDNGateway/Conf.h index 5b3496c..32794cf 100644 --- a/NXDNGateway/Conf.h +++ b/NXDNGateway/Conf.h @@ -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; diff --git a/NXDNGateway/Makefile b/NXDNGateway/Makefile index 20032a2..d9bc000 100644 --- a/NXDNGateway/Makefile +++ b/NXDNGateway/Makefile @@ -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 diff --git a/NXDNGateway/NXDNGateway.cpp b/NXDNGateway/NXDNGateway.cpp index ae8a008..8f4df31 100644 --- a/NXDNGateway/NXDNGateway.cpp +++ b/NXDNGateway/NXDNGateway.cpp @@ -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(); diff --git a/NXDNGateway/NXDNGateway.ini b/NXDNGateway/NXDNGateway.ini index d0fba44..d0aba7b 100644 --- a/NXDNGateway/NXDNGateway.ini +++ b/NXDNGateway/NXDNGateway.ini @@ -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 diff --git a/NXDNGateway/Version.h b/NXDNGateway/Version.h index b8cc636..64b1742 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200601"; +const char* VERSION = "20200603"; #endif