diff --git a/.gitignore b/.gitignore index 44bad9c..525f188 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ Debug Release x64 -MMDVMHost *.o *.opendb *.bak @@ -14,3 +13,6 @@ MMDVMHost *.user *.VC.db .vs +YSFGateway/YSFGateway +YSFParrot/YSFParrot +YSFReflector/YSFReflector diff --git a/README.md b/README.md index e17306c..4a13457 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,6 @@ The Gateway and Reflector have ini files that contain the parameters for running The MMDVM .ini file should have the IP address and port number of the client in the [System Fusion Network] settings. -They build on 32-bit and 64-bit Linux as well as on Windows using VS2015 on x86 and x64. +They build on 32-bit and 64-bit Linux as well as on Windows using Visual Studio 2017 on x86 and x64. This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden. diff --git a/YSFGateway/APRSWriter.cpp b/YSFGateway/APRSWriter.cpp index 43a2f61..eac1077 100644 --- a/YSFGateway/APRSWriter.cpp +++ b/YSFGateway/APRSWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2010-2014,2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -34,7 +34,8 @@ m_txFrequency(0U), m_rxFrequency(0U), m_latitude(0.0F), m_longitude(0.0F), -m_height(0) +m_height(0), +m_desc() { assert(!callsign.empty()); assert(!password.empty()); @@ -53,17 +54,19 @@ CAPRSWriter::~CAPRSWriter() { } -void CAPRSWriter::setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height) +void CAPRSWriter::setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height, const std::string& desc) { m_txFrequency = txFrequency; m_rxFrequency = rxFrequency; m_latitude = latitude; m_longitude = longitude; m_height = height; + m_desc = desc; } bool CAPRSWriter::open() { + m_idTimer.start(); return m_thread->start(); } @@ -146,15 +149,15 @@ void CAPRSWriter::sendIdFrames() if (m_latitude == 0.0F && m_longitude == 0.0F) return; - char desc[100U]; + char desc[200U]; if (m_txFrequency != 0U) { float offset = float(int(m_rxFrequency) - int(m_txFrequency)) / 1000000.0F; - ::sprintf(desc, "MMDVM Voice %.5lfMHz %c%.4lfMHz", - float(m_txFrequency) / 1000000.0F, + ::sprintf(desc, "MMDVM Voice %.5LfMHz %c%.4lfMHz%s%s", + (long double)(m_txFrequency) / 1000000.0F, offset < 0.0F ? '-' : '+', - ::fabs(offset)); + ::fabs(offset), m_desc.empty() ? "" : ", ", m_desc.c_str()); } else { - ::strcpy(desc, "MMDVM Voice"); + ::sprintf(desc, "MMDVM Voice%s%s", m_desc.empty() ? "" : ", ", m_desc.c_str()); } const char* band = "4m"; @@ -179,10 +182,10 @@ void CAPRSWriter::sendIdFrames() longitude = (tempLong - longitude) * 60.0 + longitude * 100.0; char lat[20U]; - ::sprintf(lat, "%04.2lf", latitude); + ::sprintf(lat, "%07.2lf", latitude); char lon[20U]; - ::sprintf(lon, "%05.2lf", longitude); + ::sprintf(lon, "%08.2lf", longitude); std::string server = m_callsign; size_t pos = server.find_first_of('-'); diff --git a/YSFGateway/APRSWriter.h b/YSFGateway/APRSWriter.h index 4095bc5..442dd17 100644 --- a/YSFGateway/APRSWriter.h +++ b/YSFGateway/APRSWriter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010,2011,2012,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2010,2011,2012,2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -31,7 +31,7 @@ public: bool open(); - void setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height); + void setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height, const std::string& desc); void write(const unsigned char* source, const char* type, unsigned char radio, float latitude, float longitude); @@ -49,6 +49,7 @@ private: float m_latitude; float m_longitude; int m_height; + std::string m_desc; void sendIdFrames(); }; diff --git a/YSFGateway/Conf.cpp b/YSFGateway/Conf.cpp index 8b11600..4ad3813 100644 --- a/YSFGateway/Conf.cpp +++ b/YSFGateway/Conf.cpp @@ -60,6 +60,7 @@ m_aprsEnabled(false), m_aprsServer(), m_aprsPort(0U), m_aprsPassword(), +m_aprsDescription(), m_networkEnabled(false), m_networkPort(0U), m_networkHosts(), @@ -68,6 +69,7 @@ m_networkParrotAddress("127.0.0.1"), m_networkParrotPort(0U), m_networkStartup(), m_networkInactivityTimeout(0U), +m_networkRevert(false), m_networkDebug(false) { } @@ -169,6 +171,8 @@ bool CConf::read() m_aprsPort = (unsigned int)::atoi(value); else if (::strcmp(key, "Password") == 0) m_aprsPassword = value; + else if (::strcmp(key, "Description") == 0) + m_aprsDescription = value; } else if (section == SECTION_NETWORK) { if (::strcmp(key, "Enable") == 0) m_networkEnabled = ::atoi(value) == 1; @@ -186,6 +190,8 @@ bool CConf::read() m_networkStartup = value; else if (::strcmp(key, "InactivityTimeout") == 0) m_networkInactivityTimeout = (unsigned int)::atoi(value); + else if (::strcmp(key, "Revert") == 0) + m_networkRevert = ::atoi(value) == 1; else if (::strcmp(key, "Debug") == 0) m_networkDebug = ::atoi(value) == 1; } @@ -311,6 +317,11 @@ std::string CConf::getAPRSPassword() const return m_aprsPassword; } +std::string CConf::getAPRSDescription() const +{ + return m_aprsDescription; +} + bool CConf::getNetworkEnabled() const { return m_networkEnabled; @@ -351,6 +362,11 @@ unsigned int CConf::getNetworkInactivityTimeout() const return m_networkInactivityTimeout; } +bool CConf::getNetworkRevert() const +{ + return m_networkRevert; +} + bool CConf::getNetworkDebug() const { return m_networkDebug; diff --git a/YSFGateway/Conf.h b/YSFGateway/Conf.h index 338ed5f..71cfde2 100644 --- a/YSFGateway/Conf.h +++ b/YSFGateway/Conf.h @@ -60,6 +60,7 @@ public: std::string getAPRSServer() const; unsigned int getAPRSPort() const; std::string getAPRSPassword() const; + std::string getAPRSDescription() const; // The Network section bool getNetworkEnabled() const; @@ -70,6 +71,7 @@ public: unsigned int getNetworkParrotPort() const; std::string getNetworkStartup() const; unsigned int getNetworkInactivityTimeout() const; + bool getNetworkRevert() const; bool getNetworkDebug() const; private: @@ -100,6 +102,7 @@ private: std::string m_aprsServer; unsigned int m_aprsPort; std::string m_aprsPassword; + std::string m_aprsDescription; bool m_networkEnabled; unsigned int m_networkPort; @@ -109,6 +112,7 @@ private: unsigned int m_networkParrotPort; std::string m_networkStartup; unsigned int m_networkInactivityTimeout; + bool m_networkRevert; bool m_networkDebug; }; diff --git a/YSFGateway/DTMF.cpp b/YSFGateway/DTMF.cpp new file mode 100644 index 0000000..b1658fc --- /dev/null +++ b/YSFGateway/DTMF.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2012,2013,2015,2017 by Jonathan Naylor G4KLX + * Copyright (C) 2011 by DV Developer Group. DJ0ABR + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DTMF.h" + +#include "Utils.h" + +const unsigned char DTMF_VD2_MASK[] = { 0xCCU, 0xCCU, 0xDDU, 0xDDU, 0xEEU, 0xEEU, 0xFFU, 0xFFU, 0xEEU, 0xEEU, 0xDDU, 0x99U, 0x98U }; +const unsigned char DTMF_VD2_SIG[] = { 0x08U, 0x80U, 0xC9U, 0x10U, 0x26U, 0xA0U, 0xE3U, 0x31U, 0xE2U, 0xE6U, 0xD5U, 0x08U, 0x88U }; + +const unsigned char DTMF_VD2_SYM_MASK[] = { 0x33U, 0x33U, 0x22U, 0x22U, 0x11U, 0x11U, 0x11U, 0x11U, 0x22U, 0x66U, 0x66U }; +const unsigned char DTMF_VD2_SYM0[] = { 0x33U, 0x11U, 0x22U, 0x02U, 0x00U, 0x00U, 0x01U, 0x11U, 0x00U, 0x04U, 0x62U }; +const unsigned char DTMF_VD2_SYM1[] = { 0x33U, 0x10U, 0x20U, 0x20U, 0x00U, 0x01U, 0x01U, 0x10U, 0x00U, 0x04U, 0x62U }; +const unsigned char DTMF_VD2_SYM2[] = { 0x22U, 0x23U, 0x02U, 0x02U, 0x00U, 0x10U, 0x01U, 0x01U, 0x00U, 0x04U, 0x62U }; +const unsigned char DTMF_VD2_SYM3[] = { 0x22U, 0x22U, 0x00U, 0x20U, 0x00U, 0x11U, 0x01U, 0x00U, 0x00U, 0x04U, 0x62U }; +const unsigned char DTMF_VD2_SYM4[] = { 0x11U, 0x11U, 0x22U, 0x02U, 0x01U, 0x00U, 0x00U, 0x11U, 0x00U, 0x06U, 0x44U }; +const unsigned char DTMF_VD2_SYM5[] = { 0x11U, 0x10U, 0x20U, 0x20U, 0x01U, 0x01U, 0x00U, 0x10U, 0x00U, 0x06U, 0x44U }; +const unsigned char DTMF_VD2_SYM6[] = { 0x00U, 0x23U, 0x02U, 0x02U, 0x01U, 0x10U, 0x00U, 0x01U, 0x00U, 0x06U, 0x44U }; +const unsigned char DTMF_VD2_SYM7[] = { 0x00U, 0x22U, 0x00U, 0x20U, 0x01U, 0x11U, 0x00U, 0x00U, 0x00U, 0x06U, 0x44U }; +const unsigned char DTMF_VD2_SYM8[] = { 0x33U, 0x11U, 0x22U, 0x02U, 0x10U, 0x00U, 0x11U, 0x11U, 0x22U, 0x60U, 0x22U }; +const unsigned char DTMF_VD2_SYM9[] = { 0x33U, 0x10U, 0x20U, 0x20U, 0x10U, 0x01U, 0x11U, 0x10U, 0x22U, 0x60U, 0x22U }; +const unsigned char DTMF_VD2_SYMA[] = { 0x22U, 0x23U, 0x02U, 0x02U, 0x10U, 0x10U, 0x11U, 0x01U, 0x22U, 0x60U, 0x22U }; +const unsigned char DTMF_VD2_SYMB[] = { 0x22U, 0x22U, 0x00U, 0x20U, 0x10U, 0x11U, 0x11U, 0x00U, 0x22U, 0x60U, 0x22U }; +const unsigned char DTMF_VD2_SYMC[] = { 0x11U, 0x11U, 0x22U, 0x02U, 0x11U, 0x00U, 0x10U, 0x11U, 0x22U, 0x62U, 0x04U }; +const unsigned char DTMF_VD2_SYMD[] = { 0x11U, 0x10U, 0x20U, 0x20U, 0x11U, 0x01U, 0x10U, 0x10U, 0x22U, 0x62U, 0x04U }; +const unsigned char DTMF_VD2_SYMS[] = { 0x00U, 0x23U, 0x02U, 0x02U, 0x11U, 0x10U, 0x10U, 0x01U, 0x22U, 0x62U, 0x04U }; +const unsigned char DTMF_VD2_SYMH[] = { 0x00U, 0x22U, 0x00U, 0x20U, 0x11U, 0x11U, 0x10U, 0x00U, 0x22U, 0x62U, 0x04U }; + +CDTMF::CDTMF() : +m_data(), +m_command(), +m_pressed(false), +m_releaseCount(0U), +m_pressCount(0U), +m_lastChar(' ') +{ +} + +CDTMF::~CDTMF() +{ +} + +WX_STATUS CDTMF::decodeVDMode2(const unsigned char* payload, bool end) +{ + assert(payload != NULL); + + payload += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES; + + for (unsigned int offset = 5U; offset < 90U; offset += 18U) { + WX_STATUS status = decodeVDMode2Slice(payload + offset, end); + if (status != WXS_NONE) + return status; + } + + return WXS_NONE; +} + +WX_STATUS CDTMF::decodeVDMode2Slice(const unsigned char* ambe, bool end) +{ + // DTMF begins with these byte values + if (!end && (ambe[0] & DTMF_VD2_MASK[0]) == DTMF_VD2_SIG[0] && (ambe[1] & DTMF_VD2_MASK[1]) == DTMF_VD2_SIG[1] && + (ambe[2] & DTMF_VD2_MASK[2]) == DTMF_VD2_SIG[2] && (ambe[3] & DTMF_VD2_MASK[3]) == DTMF_VD2_SIG[3] && + (ambe[4] & DTMF_VD2_MASK[4]) == DTMF_VD2_SIG[4] && (ambe[5] & DTMF_VD2_MASK[5]) == DTMF_VD2_SIG[5] && + (ambe[6] & DTMF_VD2_MASK[6]) == DTMF_VD2_SIG[6] && (ambe[7] & DTMF_VD2_MASK[7]) == DTMF_VD2_SIG[7] && + (ambe[8] & DTMF_VD2_MASK[8]) == DTMF_VD2_SIG[8] && (ambe[9] & DTMF_VD2_MASK[9]) == DTMF_VD2_SIG[9] && + (ambe[10] & DTMF_VD2_MASK[10]) == DTMF_VD2_SIG[10] && (ambe[11] & DTMF_VD2_MASK[11]) == DTMF_VD2_SIG[11] && + (ambe[12] & DTMF_VD2_MASK[12]) == DTMF_VD2_SIG[12]) { + unsigned char sym0 = ambe[0] & DTMF_VD2_SYM_MASK[0]; + unsigned char sym1 = ambe[1] & DTMF_VD2_SYM_MASK[1]; + unsigned char sym2 = ambe[2] & DTMF_VD2_SYM_MASK[2]; + unsigned char sym3 = ambe[3] & DTMF_VD2_SYM_MASK[3]; + unsigned char sym4 = ambe[4] & DTMF_VD2_SYM_MASK[4]; + unsigned char sym5 = ambe[5] & DTMF_VD2_SYM_MASK[5]; + unsigned char sym6 = ambe[8] & DTMF_VD2_SYM_MASK[6]; + unsigned char sym7 = ambe[9] & DTMF_VD2_SYM_MASK[7]; + unsigned char sym8 = ambe[10] & DTMF_VD2_SYM_MASK[8]; + unsigned char sym9 = ambe[11] & DTMF_VD2_SYM_MASK[9]; + unsigned char sym10 = ambe[12] & DTMF_VD2_SYM_MASK[10]; + + char c = ' '; + if (sym0 == DTMF_VD2_SYM0[0] && sym1 == DTMF_VD2_SYM0[1] && sym2 == DTMF_VD2_SYM0[2] && sym3 == DTMF_VD2_SYM0[3] && sym4 == DTMF_VD2_SYM0[4] && sym5 == DTMF_VD2_SYM0[5] && sym6 == DTMF_VD2_SYM0[6] && sym7 == DTMF_VD2_SYM0[7] && sym8 == DTMF_VD2_SYM0[8] && sym9 == DTMF_VD2_SYM0[9] && sym10 == DTMF_VD2_SYM0[10]) + c = '0'; + else if (sym0 == DTMF_VD2_SYM1[0] && sym1 == DTMF_VD2_SYM1[1] && sym2 == DTMF_VD2_SYM1[2] && sym3 == DTMF_VD2_SYM1[3] && sym4 == DTMF_VD2_SYM1[4] && sym5 == DTMF_VD2_SYM1[5] && sym6 == DTMF_VD2_SYM1[6] && sym7 == DTMF_VD2_SYM1[7] && sym8 == DTMF_VD2_SYM1[8] && sym9 == DTMF_VD2_SYM1[9] && sym10 == DTMF_VD2_SYM1[10]) + c = '1'; + else if (sym0 == DTMF_VD2_SYM2[0] && sym1 == DTMF_VD2_SYM2[1] && sym2 == DTMF_VD2_SYM2[2] && sym3 == DTMF_VD2_SYM2[3] && sym4 == DTMF_VD2_SYM2[4] && sym5 == DTMF_VD2_SYM2[5] && sym6 == DTMF_VD2_SYM2[6] && sym7 == DTMF_VD2_SYM2[7] && sym8 == DTMF_VD2_SYM2[8] && sym9 == DTMF_VD2_SYM2[9] && sym10 == DTMF_VD2_SYM2[10]) + c = '2'; + else if (sym0 == DTMF_VD2_SYM3[0] && sym1 == DTMF_VD2_SYM3[1] && sym2 == DTMF_VD2_SYM3[2] && sym3 == DTMF_VD2_SYM3[3] && sym4 == DTMF_VD2_SYM3[4] && sym5 == DTMF_VD2_SYM3[5] && sym6 == DTMF_VD2_SYM3[6] && sym7 == DTMF_VD2_SYM3[7] && sym8 == DTMF_VD2_SYM3[8] && sym9 == DTMF_VD2_SYM3[9] && sym10 == DTMF_VD2_SYM3[10]) + c = '3'; + else if (sym0 == DTMF_VD2_SYM4[0] && sym1 == DTMF_VD2_SYM4[1] && sym2 == DTMF_VD2_SYM4[2] && sym3 == DTMF_VD2_SYM4[3] && sym4 == DTMF_VD2_SYM4[4] && sym5 == DTMF_VD2_SYM4[5] && sym6 == DTMF_VD2_SYM4[6] && sym7 == DTMF_VD2_SYM4[7] && sym8 == DTMF_VD2_SYM4[8] && sym9 == DTMF_VD2_SYM4[9] && sym10 == DTMF_VD2_SYM4[10]) + c = '4'; + else if (sym0 == DTMF_VD2_SYM5[0] && sym1 == DTMF_VD2_SYM5[1] && sym2 == DTMF_VD2_SYM5[2] && sym3 == DTMF_VD2_SYM5[3] && sym4 == DTMF_VD2_SYM5[4] && sym5 == DTMF_VD2_SYM5[5] && sym6 == DTMF_VD2_SYM5[6] && sym7 == DTMF_VD2_SYM5[7] && sym8 == DTMF_VD2_SYM5[8] && sym9 == DTMF_VD2_SYM5[9] && sym10 == DTMF_VD2_SYM5[10]) + c = '5'; + else if (sym0 == DTMF_VD2_SYM6[0] && sym1 == DTMF_VD2_SYM6[1] && sym2 == DTMF_VD2_SYM6[2] && sym3 == DTMF_VD2_SYM6[3] && sym4 == DTMF_VD2_SYM6[4] && sym5 == DTMF_VD2_SYM6[5] && sym6 == DTMF_VD2_SYM6[6] && sym7 == DTMF_VD2_SYM6[7] && sym8 == DTMF_VD2_SYM6[8] && sym9 == DTMF_VD2_SYM6[9] && sym10 == DTMF_VD2_SYM6[10]) + c = '6'; + else if (sym0 == DTMF_VD2_SYM7[0] && sym1 == DTMF_VD2_SYM7[1] && sym2 == DTMF_VD2_SYM7[2] && sym3 == DTMF_VD2_SYM7[3] && sym4 == DTMF_VD2_SYM7[4] && sym5 == DTMF_VD2_SYM7[5] && sym6 == DTMF_VD2_SYM7[6] && sym7 == DTMF_VD2_SYM7[7] && sym8 == DTMF_VD2_SYM7[8] && sym9 == DTMF_VD2_SYM7[9] && sym10 == DTMF_VD2_SYM7[10]) + c = '7'; + else if (sym0 == DTMF_VD2_SYM8[0] && sym1 == DTMF_VD2_SYM8[1] && sym2 == DTMF_VD2_SYM8[2] && sym3 == DTMF_VD2_SYM8[3] && sym4 == DTMF_VD2_SYM8[4] && sym5 == DTMF_VD2_SYM8[5] && sym6 == DTMF_VD2_SYM8[6] && sym7 == DTMF_VD2_SYM8[7] && sym8 == DTMF_VD2_SYM8[8] && sym9 == DTMF_VD2_SYM8[9] && sym10 == DTMF_VD2_SYM8[10]) + c = '8'; + else if (sym0 == DTMF_VD2_SYM9[0] && sym1 == DTMF_VD2_SYM9[1] && sym2 == DTMF_VD2_SYM9[2] && sym3 == DTMF_VD2_SYM9[3] && sym4 == DTMF_VD2_SYM9[4] && sym5 == DTMF_VD2_SYM9[5] && sym6 == DTMF_VD2_SYM9[6] && sym7 == DTMF_VD2_SYM9[7] && sym8 == DTMF_VD2_SYM9[8] && sym9 == DTMF_VD2_SYM9[9] && sym10 == DTMF_VD2_SYM9[10]) + c = '9'; + else if (sym0 == DTMF_VD2_SYMA[0] && sym1 == DTMF_VD2_SYMA[1] && sym2 == DTMF_VD2_SYMA[2] && sym3 == DTMF_VD2_SYMA[3] && sym4 == DTMF_VD2_SYMA[4] && sym5 == DTMF_VD2_SYMA[5] && sym6 == DTMF_VD2_SYMA[6] && sym7 == DTMF_VD2_SYMA[7] && sym8 == DTMF_VD2_SYMA[8] && sym9 == DTMF_VD2_SYMA[9] && sym10 == DTMF_VD2_SYMA[10]) + c = 'A'; + else if (sym0 == DTMF_VD2_SYMB[0] && sym1 == DTMF_VD2_SYMB[1] && sym2 == DTMF_VD2_SYMB[2] && sym3 == DTMF_VD2_SYMB[3] && sym4 == DTMF_VD2_SYMB[4] && sym5 == DTMF_VD2_SYMB[5] && sym6 == DTMF_VD2_SYMB[6] && sym7 == DTMF_VD2_SYMB[7] && sym8 == DTMF_VD2_SYMB[8] && sym9 == DTMF_VD2_SYMB[9] && sym10 == DTMF_VD2_SYMB[10]) + c = 'B'; + else if (sym0 == DTMF_VD2_SYMC[0] && sym1 == DTMF_VD2_SYMC[1] && sym2 == DTMF_VD2_SYMC[2] && sym3 == DTMF_VD2_SYMC[3] && sym4 == DTMF_VD2_SYMC[4] && sym5 == DTMF_VD2_SYMC[5] && sym6 == DTMF_VD2_SYMC[6] && sym7 == DTMF_VD2_SYMC[7] && sym8 == DTMF_VD2_SYMC[8] && sym9 == DTMF_VD2_SYMC[9] && sym10 == DTMF_VD2_SYMC[10]) + c = 'C'; + else if (sym0 == DTMF_VD2_SYMD[0] && sym1 == DTMF_VD2_SYMD[1] && sym2 == DTMF_VD2_SYMD[2] && sym3 == DTMF_VD2_SYMD[3] && sym4 == DTMF_VD2_SYMD[4] && sym5 == DTMF_VD2_SYMD[5] && sym6 == DTMF_VD2_SYMD[6] && sym7 == DTMF_VD2_SYMD[7] && sym8 == DTMF_VD2_SYMD[8] && sym9 == DTMF_VD2_SYMD[9] && sym10 == DTMF_VD2_SYMD[10]) + c = 'D'; + else if (sym0 == DTMF_VD2_SYMS[0] && sym1 == DTMF_VD2_SYMS[1] && sym2 == DTMF_VD2_SYMS[2] && sym3 == DTMF_VD2_SYMS[3] && sym4 == DTMF_VD2_SYMS[4] && sym5 == DTMF_VD2_SYMS[5] && sym6 == DTMF_VD2_SYMS[6] && sym7 == DTMF_VD2_SYMS[7] && sym8 == DTMF_VD2_SYMS[8] && sym9 == DTMF_VD2_SYMS[9] && sym10 == DTMF_VD2_SYMS[10]) + c = '*'; + else if (sym0 == DTMF_VD2_SYMH[0] && sym1 == DTMF_VD2_SYMH[1] && sym2 == DTMF_VD2_SYMH[2] && sym3 == DTMF_VD2_SYMH[3] && sym4 == DTMF_VD2_SYMH[4] && sym5 == DTMF_VD2_SYMH[5] && sym6 == DTMF_VD2_SYMH[6] && sym7 == DTMF_VD2_SYMH[7] && sym8 == DTMF_VD2_SYMH[8] && sym9 == DTMF_VD2_SYMH[9] && sym10 == DTMF_VD2_SYMH[10]) + c = '#'; + + if (c == m_lastChar) { + m_pressCount++; + } else { + m_lastChar = c; + m_pressCount = 0U; + } + + if (c != ' ' && !m_pressed && m_pressCount >= 3U) { + m_data += c; + m_releaseCount = 0U; + m_pressed = true; + } + + return validate(); + } else { + // If it is not a DTMF Code + if ((end || m_releaseCount >= 100U) && m_data.length() > 0U) { + m_command = m_data; + m_data.clear(); + m_releaseCount = 0U; + } + + m_pressed = false; + m_releaseCount++; + m_pressCount = 0U; + m_lastChar = ' '; + + return validate(); + } +} + +WX_STATUS CDTMF::validate() const +{ + if (m_command.length() != 6U) + return WXS_NONE; + + if (m_command.at(0U) != '#') + return WXS_NONE; + + for (unsigned int i = 1U; i <= 6U; i++) { + if (m_command.at(1U) < '0' || m_command.at(1U) > '9') + return WXS_NONE; + } + + if (m_command == "#99999") + return WXS_DISCONNECT; + + return WXS_CONNECT; +} + +std::string CDTMF::getReflector() +{ + std::string command = m_command; + reset(); + + return command.substr(1U); +} + +void CDTMF::reset() +{ + m_data.clear(); + m_command.clear(); + m_pressed = false; + m_pressCount = 0U; + m_releaseCount = 0U; + m_lastChar = ' '; +} diff --git a/YSFGateway/DTMF.h b/YSFGateway/DTMF.h new file mode 100644 index 0000000..f73dfb9 --- /dev/null +++ b/YSFGateway/DTMF.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012,2013,2017 by Jonathan Naylor G4KLX + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DTMF_H +#define DTMF_H + +#include "WiresX.h" + +#include + +class CDTMF { +public: + CDTMF(); + ~CDTMF(); + + WX_STATUS decodeVDMode2(const unsigned char* payload, bool end); + + std::string getReflector(); + + void reset(); + +private: + std::string m_data; + std::string m_command; + bool m_pressed; + unsigned int m_releaseCount; + unsigned int m_pressCount; + char m_lastChar; + + WX_STATUS decodeVDMode2Slice(const unsigned char* ambe, bool end); + WX_STATUS validate() const; +}; + +#endif diff --git a/YSFGateway/GPS.cpp b/YSFGateway/GPS.cpp index 8c26e5f..8d0012e 100644 --- a/YSFGateway/GPS.cpp +++ b/YSFGateway/GPS.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -49,9 +49,9 @@ CGPS::~CGPS() delete[] m_buffer; } -void CGPS::setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height) +void CGPS::setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height, const std::string& desc) { - m_writer.setInfo(rxFrequency, rxFrequency, latitude, longitude, height); + m_writer.setInfo(txFrequency, rxFrequency, latitude, longitude, height, desc); } bool CGPS::open() @@ -196,8 +196,8 @@ void CGPS::transmitGPS(const unsigned char* source) lon_deg = b - 0x76U; // 0 to 9 else if (b >= 0x6CU && b <= 0x75U) lon_deg = 100U + (b - 0x6CU); // 100 to 109 - else if (b >= 0x16U && b <= 0x6BU) - lon_deg = 110U + (b - 0x16U); // 110 to 179 + else if (b >= 0x26U && b <= 0x6BU) + lon_deg = 110U + (b - 0x26U); // 110 to 179 else return; // error/unknown } else if (b == 0x30U) { diff --git a/YSFGateway/GPS.h b/YSFGateway/GPS.h index 379f3b7..f168dfd 100644 --- a/YSFGateway/GPS.h +++ b/YSFGateway/GPS.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -28,7 +28,7 @@ public: CGPS(const std::string& callsign, const std::string& suffix, const std::string& password, const std::string& address, unsigned int port); ~CGPS(); - void setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height); + void setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height, const std::string& desc); bool open(); diff --git a/YSFGateway/Makefile b/YSFGateway/Makefile index 2c25ec8..5646b0c 100644 --- a/YSFGateway/Makefile +++ b/YSFGateway/Makefile @@ -4,7 +4,7 @@ CFLAGS = -g -O3 -Wall -std=c++0x -pthread LIBS = -lm -lpthread LDFLAGS = -g -OBJECTS = APRSWriterThread.o APRSWriter.o Conf.o CRC.o Golay24128.o GPS.o Log.o Network.o Reflectors.o StopWatch.o Sync.o TCPSocket.o Thread.o Timer.o \ +OBJECTS = APRSWriterThread.o APRSWriter.o Conf.o CRC.o DTMF.o Golay24128.o GPS.o Log.o Network.o Reflectors.o StopWatch.o Sync.o TCPSocket.o Thread.o Timer.o \ UDPSocket.o Utils.o WiresX.o YSFConvolution.o YSFFICH.o YSFGateway.o YSFPayload.o all: YSFGateway diff --git a/YSFGateway/Makefile.Solaris b/YSFGateway/Makefile.Solaris index b458fd6..83461e4 100644 --- a/YSFGateway/Makefile.Solaris +++ b/YSFGateway/Makefile.Solaris @@ -4,7 +4,7 @@ CFLAGS = -g -O3 -Wall -std=c++0x -pthread LIBS = -lm -lpthread -lsocket LDFLAGS = -g -OBJECTS = APRSWriterThread.o APRSWriter.o Conf.o CRC.o Golay24128.o GPS.o Log.o Network.o Reflectors.o StopWatch.o Sync.o TCPSocket.o Thread.o Timer.o \ +OBJECTS = APRSWriterThread.o APRSWriter.o Conf.o CRC.o DTMF.o Golay24128.o GPS.o Log.o Network.o Reflectors.o StopWatch.o Sync.o TCPSocket.o Thread.o Timer.o \ UDPSocket.o Utils.o WiresX.o YSFConvolution.o YSFFICH.o YSFGateway.o YSFPayload.o all: YSFGateway diff --git a/YSFGateway/Network.cpp b/YSFGateway/Network.cpp index 02945a2..f643a43 100644 --- a/YSFGateway/Network.cpp +++ b/YSFGateway/Network.cpp @@ -93,7 +93,7 @@ void CNetwork::setDestination(const in_addr& address, unsigned int port) m_port = port; } -void CNetwork::setDestination() +void CNetwork::clearDestination() { m_address.s_addr = INADDR_NONE; m_port = 0U; diff --git a/YSFGateway/Network.h b/YSFGateway/Network.h index e5c90be..fc023c5 100644 --- a/YSFGateway/Network.h +++ b/YSFGateway/Network.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2014,2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -35,7 +35,7 @@ public: bool open(); void setDestination(const in_addr& address, unsigned int port); - void setDestination(); + void clearDestination(); bool write(const unsigned char* data); diff --git a/YSFGateway/Reflectors.cpp b/YSFGateway/Reflectors.cpp index 997808e..d2ac8a6 100644 --- a/YSFGateway/Reflectors.cpp +++ b/YSFGateway/Reflectors.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -30,7 +30,8 @@ CReflectors::CReflectors(const std::string& hostsFile, unsigned int reloadTime) m_hostsFile(hostsFile), m_parrotAddress(), m_parrotPort(0U), -m_reflectors(), +m_newReflectors(), +m_currReflectors(), m_search(), m_timer(1000U, reloadTime * 60U) { @@ -40,10 +41,14 @@ m_timer(1000U, reloadTime * 60U) CReflectors::~CReflectors() { - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) + for (std::vector::iterator it = m_newReflectors.begin(); it != m_newReflectors.end(); ++it) delete *it; - m_reflectors.clear(); + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) + delete *it; + + m_newReflectors.clear(); + m_currReflectors.clear(); } static bool refComparison(const CYSFReflector* r1, const CYSFReflector* r2) @@ -71,11 +76,10 @@ void CReflectors::setParrot(const std::string& address, unsigned int port) bool CReflectors::load() { - // Clear out the old reflector list - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) + for (std::vector::iterator it = m_newReflectors.begin(); it != m_newReflectors.end(); ++it) delete *it; - m_reflectors.clear(); + m_newReflectors.clear(); FILE* fp = ::fopen(m_hostsFile.c_str(), "rt"); if (fp != NULL) { @@ -107,7 +111,7 @@ bool CReflectors::load() refl->m_name.resize(16U, ' '); refl->m_desc.resize(14U, ' '); - m_reflectors.push_back(refl); + m_newReflectors.push_back(refl); } } } @@ -115,7 +119,7 @@ bool CReflectors::load() ::fclose(fp); } - size_t size = m_reflectors.size(); + size_t size = m_newReflectors.size(); LogInfo("Loaded %u YSF reflectors", size); // Add the Parrot entry @@ -127,22 +131,22 @@ bool CReflectors::load() refl->m_address = CUDPSocket::lookup(m_parrotAddress); refl->m_port = m_parrotPort; refl->m_count = "000"; - m_reflectors.push_back(refl); + m_newReflectors.push_back(refl); LogInfo("Loaded YSF parrot"); } - size = m_reflectors.size(); + size = m_newReflectors.size(); if (size == 0U) return false; - std::sort(m_reflectors.begin(), m_reflectors.end(), refComparison); + std::sort(m_newReflectors.begin(), m_newReflectors.end(), refComparison); return true; } CYSFReflector* CReflectors::find(const std::string& id) { - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) { + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) { if (id == (*it)->m_id) return *it; } @@ -154,7 +158,7 @@ CYSFReflector* CReflectors::find(const std::string& id) std::vector& CReflectors::current() { - return m_reflectors; + return m_currReflectors; } std::vector& CReflectors::search(const std::string& name) @@ -167,7 +171,7 @@ std::vector& CReflectors::search(const std::string& name) unsigned int len = trimmed.size(); - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) { + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) { std::string reflector = (*it)->m_name; reflector.erase(std::find_if(reflector.rbegin(), reflector.rend(), std::not1(std::ptr_fun(std::isspace))).base(), reflector.end()); std::transform(reflector.begin(), reflector.end(), reflector.begin(), ::toupper); @@ -181,6 +185,23 @@ std::vector& CReflectors::search(const std::string& name) return m_search; } +bool CReflectors::reload() +{ + if (m_newReflectors.empty()) + return false; + + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) + delete *it; + + m_currReflectors.clear(); + + m_currReflectors = m_newReflectors; + + m_newReflectors.clear(); + + return true; +} + void CReflectors::clock(unsigned int ms) { m_timer.clock(ms); diff --git a/YSFGateway/Reflectors.h b/YSFGateway/Reflectors.h index 9b15ecd..d1b1d14 100644 --- a/YSFGateway/Reflectors.h +++ b/YSFGateway/Reflectors.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -60,13 +60,16 @@ public: std::vector& search(const std::string& name); + bool reload(); + void clock(unsigned int ms); private: std::string m_hostsFile; std::string m_parrotAddress; unsigned int m_parrotPort; - std::vector m_reflectors; + std::vector m_newReflectors; + std::vector m_currReflectors; std::vector m_search; CTimer m_timer; }; diff --git a/YSFGateway/Version.h b/YSFGateway/Version.h index 9233872..b6885be 100644 --- a/YSFGateway/Version.h +++ b/YSFGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20170318"; +const char* VERSION = "20170719"; #endif diff --git a/YSFGateway/WiresX.cpp b/YSFGateway/WiresX.cpp index 9994dd4..006dd65 100644 --- a/YSFGateway/WiresX.cpp +++ b/YSFGateway/WiresX.cpp @@ -53,7 +53,7 @@ m_name(), m_command(NULL), m_txFrequency(0U), m_rxFrequency(0U), -m_timer(1000U, 2U), +m_timer(1000U, 1U), m_seqNo(0U), m_header(NULL), m_csd1(NULL), @@ -154,7 +154,13 @@ void CWiresX::setParrot(const std::string& address, unsigned int port) bool CWiresX::start() { - return m_reflectors.load(); + bool ret = m_reflectors.load(); + if (!ret) + return false; + + m_reflectors.reload(); + + return true; } WX_STATUS CWiresX::process(const unsigned char* data, const unsigned char* source, unsigned char fi, unsigned char dt, unsigned char fn, unsigned char ft) @@ -286,9 +292,18 @@ WX_STATUS CWiresX::processConnect(const unsigned char* source, const unsigned ch return WXS_CONNECT; } +void CWiresX::processConnect(CYSFReflector* reflector) +{ + m_reflector = reflector; + + m_status = WXSI_CONNECT; + m_timer.start(); +} + void CWiresX::processDisconnect(const unsigned char* source) { - ::LogDebug("Received Disconect from %10.10s", source); + if (source != NULL) + ::LogDebug("Received Disconect from %10.10s", source); m_reflector = NULL; @@ -496,13 +511,13 @@ void CWiresX::sendDXReply() for (unsigned int i = 0U; i < 5U; i++) data[i + 36U] = m_reflector->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < m_reflector->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + 41U] = m_reflector->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) data[i + 57U] = m_reflector->m_count.at(i); - for (unsigned int i = 0U; i < 14U && i < m_reflector->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + 70U] = m_reflector->m_desc.at(i); } @@ -563,13 +578,13 @@ void CWiresX::sendConnectReply() for (unsigned int i = 0U; i < 5U; i++) data[i + 36U] = m_reflector->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < m_reflector->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + 41U] = m_reflector->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) data[i + 57U] = m_reflector->m_count.at(i); - for (unsigned int i = 0U; i < 14U && i < m_reflector->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + 70U] = m_reflector->m_desc.at(i); data[84U] = '0'; @@ -627,6 +642,9 @@ void CWiresX::sendDisconnectReply() void CWiresX::sendAllReply() { + if (m_start == 0U) + m_reflectors.reload(); + std::vector& curr = m_reflectors.current(); unsigned char data[1100U]; @@ -667,7 +685,7 @@ void CWiresX::sendAllReply() for (unsigned int i = 0U; i < 5U; i++) data[i + offset + 1U] = refl->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < refl->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + offset + 6U] = refl->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) @@ -676,7 +694,7 @@ void CWiresX::sendAllReply() for (unsigned int i = 0U; i < 10U; i++) data[i + offset + 25U] = ' '; - for (unsigned int i = 0U; i < 14U && i < refl->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + offset + 35U] = refl->m_desc.at(i); data[offset + 49U] = 0x0DU; @@ -751,7 +769,7 @@ void CWiresX::sendSearchReply() for (unsigned int i = 0U; i < 5U; i++) data[i + offset + 1U] = refl->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < refl->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + offset + 6U] = refl->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) @@ -760,7 +778,7 @@ void CWiresX::sendSearchReply() for (unsigned int i = 0U; i < 10U; i++) data[i + offset + 25U] = ' '; - for (unsigned int i = 0U; i < 14U && i < refl->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + offset + 35U] = refl->m_desc.at(i); data[offset + 49U] = 0x0DU; diff --git a/YSFGateway/WiresX.h b/YSFGateway/WiresX.h index 5593245..6786b82 100644 --- a/YSFGateway/WiresX.h +++ b/YSFGateway/WiresX.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -55,6 +55,9 @@ public: CYSFReflector* getReflector() const; CYSFReflector* getReflector(const std::string& id); + void processConnect(CYSFReflector* reflector); + void processDisconnect(const unsigned char* source = NULL); + void clock(unsigned int ms); private: @@ -79,7 +82,6 @@ private: std::string m_search; WX_STATUS processConnect(const unsigned char* source, const unsigned char* data); - void processDisconnect(const unsigned char* source); void processDX(const unsigned char* source); void processAll(const unsigned char* source, const unsigned char* data); diff --git a/YSFGateway/YSFDefines.h b/YSFGateway/YSFDefines.h index 348d1bc..2e75625 100644 --- a/YSFGateway/YSFDefines.h +++ b/YSFGateway/YSFDefines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -40,7 +40,8 @@ const unsigned char YSF_DT_DATA_FR_MODE = 0x01U; const unsigned char YSF_DT_VD_MODE2 = 0x02U; const unsigned char YSF_DT_VOICE_FR_MODE = 0x03U; -const unsigned char YSF_CM_GROUP = 0x00U; +const unsigned char YSF_CM_GROUP1 = 0x00U; +const unsigned char YSF_CM_GROUP2 = 0x01U; const unsigned char YSF_CM_INDIVIDUAL = 0x03U; const unsigned char YSF_MR_NOT_BUSY = 0x01U; diff --git a/YSFGateway/YSFGateway.cpp b/YSFGateway/YSFGateway.cpp index 87ed8b0..0648fa6 100644 --- a/YSFGateway/YSFGateway.cpp +++ b/YSFGateway/YSFGateway.cpp @@ -80,6 +80,7 @@ m_suffix(), m_conf(configFile), m_gps(NULL), m_wiresX(NULL), +m_dtmf(NULL), m_netNetwork(NULL), m_linked(false), m_exclude(false) @@ -197,12 +198,16 @@ int CYSFGateway::run() CTimer lostTimer(1000U, 120U); CTimer pollTimer(1000U, 5U); + bool revert = m_conf.getNetworkRevert(); + std::string startup = m_conf.getNetworkStartup(); + bool networkEnabled = m_conf.getNetworkEnabled(); if (networkEnabled) { std::string fileName = m_conf.getNetworkHosts(); unsigned int reloadTime = m_conf.getNetworkReloadTime(); m_wiresX = new CWiresX(m_callsign, m_suffix, &rptNetwork, fileName, reloadTime); + m_dtmf = new CDTMF; std::string name = m_conf.getName(); unsigned int txFrequency = m_conf.getTxFrequency(); @@ -218,18 +223,19 @@ int CYSFGateway::run() m_wiresX->start(); - std::string startup = m_conf.getNetworkStartup(); if (!startup.empty()) { CYSFReflector* reflector = m_wiresX->getReflector(startup); if (reflector != NULL) { - LogMessage("Automatic connection to %5.5s", reflector->m_id.c_str()); + LogMessage("Automatic connection to %5.5s - \"%s\"", reflector->m_id.c_str(), reflector->m_name.c_str()); m_netNetwork->setDestination(reflector->m_address, reflector->m_port); m_netNetwork->writePoll(); m_netNetwork->writePoll(); m_netNetwork->writePoll(); - inactivityTimer.start(); + if (!revert) + inactivityTimer.start(); + lostTimer.start(); pollTimer.start(); @@ -269,7 +275,7 @@ int CYSFGateway::run() m_netNetwork->writeUnlink(); CYSFReflector* reflector = m_wiresX->getReflector(); - LogMessage("Connect to %5.5s has been requested by %10.10s", reflector->m_id.c_str(), buffer + 14U); + LogMessage("Connect to %5.5s - \"%s\" has been requested by %10.10s", reflector->m_id.c_str(), reflector->m_name.c_str(), buffer + 14U); m_netNetwork->setDestination(reflector->m_address, reflector->m_port); m_netNetwork->writePoll(); @@ -289,7 +295,7 @@ int CYSFGateway::run() m_netNetwork->writeUnlink(); m_netNetwork->writeUnlink(); m_netNetwork->writeUnlink(); - m_netNetwork->setDestination(); + m_netNetwork->clearDestination(); inactivityTimer.stop(); lostTimer.stop(); @@ -300,6 +306,65 @@ int CYSFGateway::run() default: break; } + + status = WXS_NONE; + switch (dt) { + case YSF_DT_VD_MODE2: + status = m_dtmf->decodeVDMode2(buffer + 35U, (buffer[34U] & 0x01U) == 0x01U); + break; + default: + break; + } + + switch (status) { + case WXS_CONNECT: { + std::string id = m_dtmf->getReflector(); + CYSFReflector* reflector = m_wiresX->getReflector(id); + if (reflector != NULL) { + m_wiresX->processConnect(reflector); + + if (m_linked) { + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + } + + LogMessage("Connect via DTMF to %5.5s - \"%s\" has been requested by %10.10s", reflector->m_id.c_str(), reflector->m_name.c_str(), buffer + 14U); + + m_netNetwork->setDestination(reflector->m_address, reflector->m_port); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + + inactivityTimer.start(); + lostTimer.start(); + pollTimer.start(); + + m_linked = true; + } + } + break; + case WXS_DISCONNECT: + if (m_linked) { + m_wiresX->processDisconnect(); + + LogMessage("Disconnect via DTMF has been requested by %10.10s", buffer + 14U); + + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + m_netNetwork->clearDestination(); + + inactivityTimer.stop(); + lostTimer.stop(); + pollTimer.stop(); + + m_linked = false; + } + break; + default: + break; + } } if (m_gps != NULL) @@ -315,6 +380,8 @@ int CYSFGateway::run() if ((buffer[34U] & 0x01U) == 0x01U) { if (m_gps != NULL) m_gps->reset(); + if (m_dtmf != NULL) + m_dtmf->reset(); m_exclude = false; } } @@ -342,17 +409,42 @@ int CYSFGateway::run() inactivityTimer.clock(ms); if (inactivityTimer.isRunning() && inactivityTimer.hasExpired()) { if (m_linked) { - LogMessage("Disconnecting due to inactivity"); + CYSFReflector* reflector = NULL; + if (revert && !startup.empty() && m_wiresX != NULL) + reflector = m_wiresX->getReflector(startup); + + if (reflector != NULL) { + LogMessage("Reverting connection to %5.5s - \"%s\"", reflector->m_id.c_str(), reflector->m_name.c_str()); + + m_wiresX->processConnect(reflector); + + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + + m_netNetwork->setDestination(reflector->m_address, reflector->m_port); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + + lostTimer.start(); + pollTimer.start(); + } else { + LogMessage("Disconnecting due to inactivity"); - m_netNetwork->writeUnlink(); - m_netNetwork->writeUnlink(); - m_netNetwork->writeUnlink(); - m_netNetwork->setDestination(); + if (m_wiresX != NULL) + m_wiresX->processDisconnect(); - lostTimer.stop(); - pollTimer.stop(); + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + m_netNetwork->clearDestination(); - m_linked = false; + lostTimer.stop(); + pollTimer.stop(); + + m_linked = false; + } } inactivityTimer.stop(); @@ -361,10 +453,16 @@ int CYSFGateway::run() lostTimer.clock(ms); if (lostTimer.isRunning() && lostTimer.hasExpired()) { LogWarning("Link has failed, polls lost"); - m_netNetwork->setDestination(); + + if (m_wiresX != NULL) + m_wiresX->processDisconnect(); + + m_netNetwork->clearDestination(); + inactivityTimer.stop(); lostTimer.stop(); pollTimer.stop(); + m_linked = false; } @@ -388,6 +486,7 @@ int CYSFGateway::run() delete m_netNetwork; delete m_wiresX; + delete m_dtmf; ::LogFinalise(); @@ -402,6 +501,7 @@ void CYSFGateway::createGPS() std::string hostname = m_conf.getAPRSServer(); unsigned int port = m_conf.getAPRSPort(); std::string password = m_conf.getAPRSPassword(); + std::string desc = m_conf.getAPRSDescription(); m_gps = new CGPS(m_callsign, m_suffix, password, hostname, port); @@ -411,7 +511,7 @@ void CYSFGateway::createGPS() float longitude = m_conf.getLongitude(); int height = m_conf.getHeight(); - m_gps->setInfo(txFrequency, rxFrequency, latitude, longitude, height); + m_gps->setInfo(txFrequency, rxFrequency, latitude, longitude, height, desc); bool ret = m_gps->open(); if (!ret) { diff --git a/YSFGateway/YSFGateway.h b/YSFGateway/YSFGateway.h index 9c3f413..ca7ee94 100644 --- a/YSFGateway/YSFGateway.h +++ b/YSFGateway/YSFGateway.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -22,6 +22,7 @@ #include "Network.h" #include "WiresX.h" #include "Conf.h" +#include "DTMF.h" #include "GPS.h" #include @@ -40,6 +41,7 @@ private: CConf m_conf; CGPS* m_gps; CWiresX* m_wiresX; + CDTMF* m_dtmf; CNetwork* m_netNetwork; bool m_linked; bool m_exclude; diff --git a/YSFGateway/YSFGateway.ini b/YSFGateway/YSFGateway.ini index 4d60d61..28043da 100644 --- a/YSFGateway/YSFGateway.ini +++ b/YSFGateway/YSFGateway.ini @@ -31,6 +31,7 @@ Enable=0 Server=euro.aprs2.net Port=14580 Password=9999 +Description=APRS Description [Network] Enable=1 @@ -38,7 +39,8 @@ Port=42000 Hosts=./YSFHosts.txt ReloadTime=60 ParrotAddress=127.0.0.1 -ParrotPort=42000 +ParrotPort=42012 # Startup= InactivityTimeout=10 +# Revert=0 Debug=0 diff --git a/YSFGateway/YSFGateway.vcxproj b/YSFGateway/YSFGateway.vcxproj index d4386bc..386e32f 100644 --- a/YSFGateway/YSFGateway.vcxproj +++ b/YSFGateway/YSFGateway.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,32 +22,32 @@ {4F82857B-D2CC-48DC-91A8-6275BDD3081B} Win32Proj YSFGateway - 8.1 + 10.0.15063.0 Application true - v140 + v141 Unicode Application false - v140 + v141 true Unicode Application true - v140 + v141 Unicode Application false - v140 + v141 true Unicode @@ -150,6 +150,7 @@ + @@ -176,6 +177,7 @@ + diff --git a/YSFGateway/YSFGateway.vcxproj.filters b/YSFGateway/YSFGateway.vcxproj.filters index 9bbd27c..20053c3 100644 --- a/YSFGateway/YSFGateway.vcxproj.filters +++ b/YSFGateway/YSFGateway.vcxproj.filters @@ -83,6 +83,9 @@ Header Files + + Header Files + @@ -148,5 +151,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/YSFGateway/YSFHosts.txt b/YSFGateway/YSFHosts.txt index 8611fa8..abd17e8 100644 --- a/YSFGateway/YSFHosts.txt +++ b/YSFGateway/YSFHosts.txt @@ -1,74 +1,165 @@ -74652;119-YSF;119-C4FM;210.178.113.106;42000;002 -77889;Alabama Link;Alabama Link;199.119.98.174;42000;008 -25223;AT Austria OE1;OE1PHS;77.117.76.174;42000;000 -44853;AT OE-Austria;Digitalforce;194.208.150.205;42000;002 -25575;BM TG-2148;BM TG-2148;85.214.119.76;42108;001 -85044;C4FM-SEOUL;C4FM DMR;210.178.113.45;42000;004 -77353;CA Canada;C4FM Ontario;76.64.129.159;42100;003 +65702;0 OE-Austria;Official;94.199.172.148;42000;001 +88236;1004 DMR;DRM C4FM CROSS;210.178.113.173;42000;000 +74652;119-YSF;TG45004 XLX170;125.129.207.86;42000;002 +89803;A.O.T. Roma;OndaTelematica;31.14.140.230;42000;000 +02034;Alabama-Link;Alabama-Link;199.119.98.174;42000;029 +64230;America-RC;YSF-TO-WIRES-X;71.209.204.22;42000;006 +38654;ARGENTINA;C4FM Team;212.237.3.87;42000;005 +59330;ARRGUS Array;Florida USA;96.94.7.200;42000;000 +42586;ARRGUS_ArrayN;Back up server;64.137.194.85;42000;000 +25223;AT Austria OE1;OE1PHS;77.117.224.174;42000;002 +00396;AT Austria OE3;OE3AAS;77.118.186.2;42100;001 +55693;AT C4FM Austria;YSF;89.185.97.38;42000;008 +04201;AU YSF001;1st WW YSF;104.167.114.230;42000;012 +93760;BE YSF-Vlaandere;C4FM Vlaandere;81.95.126.168;42000;004 +79520;BE YSF-Wallonie;C4FM Wallon;51.255.193.63;42000;004 +67661;BG Bulgaria;Sysop: LZ1LCD;95.43.222.149;42000;000 +47573;BM-EA-TG914;BM-EA-TG914;104.223.70.166;42000;003 +14341;BM-TG-208;BrMstr TG208;51.254.126.212;42000;002 +30745;BM-TG-2080;BrMstr TG2080;51.254.126.212;42080;001 +00872;BM-TG-20820;BrMstr TG20820;51.254.126.212;42020;001 +52846;BM-TG-20859;BrMstr TG20859;51.254.126.212;42059;002 +39552;BM-TG-2087;BrMstr TG2087;51.254.126.212;42007;001 +93206;BM-TG-2088;BrMstr TG2088;51.254.126.212;42008;001 +35402;BM-TG-2089;BrMstr TG2089;51.254.126.212;42009;001 +36096;BR YSF724;C4FM - DV Braz;66.55.64.14;42000;002 +85044;C4FM-SEOUL;TG45004 XLX170;121.162.91.45;42000;004 +77353;CA Canada;C4FM Ontario;144.217.241.23;42100;006 49473;CA QUEBEC;QC FR Fusion;64.34.60.44;42000;000 52796;CH JOTA;Jota CH;157.161.57.65;42001;000 -59050;CL CE3FCM;ysfreflector;190.161.179.247;42000;000 -04523;CT CATALANA;C4FM Catalunya;85.214.119.76;42100;001 -30549;CT WIRESCAT;C4FM Catalunya;85.214.119.76;42000;001 -26541;CZ Czech;TG2300 DCS019V;80.250.3.114;42000;003 -62829;DE Germany;TG26208;213.202.229.15;42000;010 -10322;DE Germany2;no bridge;213.202.229.15;42001;001 -00561;DVSwitch NA;North America;45.62.252.188;42000;003 -98529;ES ED2ZAE;YSF DE EA2RCF;85.214.114.27;42000;000 -62723;ES Wires-X;27187 Wires X;89.40.117.67;42000;006 -62659;ES YSF214;C4FM Bizkaia;89.36.214.120;42000;002 +59050;CL CE3FCM;ysfreflector;190.161.179.169;42000;000 +80337;CN China #1;C4FM YSF;120.234.41.144;42000;008 +82442;CN China #2;C4FM Guangzhou;218.19.147.38;42000;000 +86319;CN China #3;C4FM;123.58.6.137;42002;026 +30490;CO 4 KILO MIKE;Antioquia;190.159.68.105;43000;000 +04523;CT CATALANA;C4FM Catalunya;85.214.119.76;42000;000 +30549;CT WIRESCAT;C4FM Catalunya;85.214.119.76;42001;005 +26541;CZ Czech;TG2300 DCS019V;80.250.3.114;42000;008 +58770;CZ YSF Praha;YSF CZ;185.32.183.148;42000;000 +80861;DE DL-NORD;AFu-Nord.de;5.45.96.68;42000;000 +54919;DE DL-NORDWEST;Nordwest-DL;91.12.55.157;42000;007 +62829;DE Germany;TG26208;213.202.229.15;42000;031 +10322;DE Germany2;no bridge;213.202.229.15;42001;000 +92469;DE Hessen;SysOP:DL5RFK;193.70.38.68;42000;001 +74154;DE PEGASUS;dl0bza.de;78.46.11.65;42000;014 +20548;DE PEGASUS2;dl0bza.de;78.46.11.65;42001;000 +55966;DE Thueringen;Thueringen;37.26.200.222;42000;001 +94179;Digiland;Italia;212.227.203.37;42000;000 +68785;Digiland_2;Italia;185.206.147.131;42000;000 +68899;Digiland_3;Italia;85.217.170.178;42000;000 +00561;DVSwitch NA;North America;44.103.32.18;42000;000 +94533;EA Distrito 1;Wires X Spain;104.223.72.8;42000;000 +42493;EA Distrito 2;EDT;185.47.129.230;42000;002 +42493;EA Distrito 2;EDT;185.47.129.230;42000;002 +48495;EA Distrito 3;Wires X Spain;89.38.150.252;42000;000 +62980;EA Distrito 4;REM SPAIN;212.237.0.67;42000;001 +39908;EA Distrito 5;YSF EALINK;216.86.147.198;42000;000 +58314;EA Distrito 7;RC Veleta;212.237.11.53;42000;001 +31236;EA DMR+;DMR+ 4370;198.96.90.144;42000;000 +37172;EA Sevilla;Prov Sevilla;204.44.93.190;42000;003 +01439;EMCOM SPAIN;Emergency;212.237.17.133;42000;000 +32027;ES ADER;ASSOCIACIO;80.211.226.198;42000;003 +98529;ES ED2ZAE;Multiporpouse;94.177.237.192;42000;001 +15642;ES REM SPAIN;REM YSF REF;95.39.166.7;42000;000 +60318;ES Wires X;WIRES X SPAIN;80.211.236.189;42000;015 +62659;ES YSF214;C4FM Net;89.36.214.120;42000;000 08054;FON-Gateway;AllModes-GW;185.109.201.81;42000;001 -60284;FR YSF-Alsace;ALS(F) ROOM;91.121.136.94;42000;000 -91991;FR YSF-BM937;Brandmeister93;51.254.133.61;42000;001 -58617;FR YSF-France;Fusion France;87.98.132.205;42000;022 -34264;FR YSF-Urgences;Fusion France;87.98.132.205;42020;002 -33751;FUSION-ITALY;Italy YSFR;91.134.133.255;42000;000 -35483;FUSION-KOREA;YSF450 KOREA;210.178.113.238;42000;000 -89164;FUSIONBE2;FusionBelgium;81.95.126.168;42000;001 -91767;GB Fusion Kernow;Fusion SW UK;78.146.3.0;43000;004 -62928;HBLINK EA5GVK;HBLINK EA5GVK;95.39.140.240;42000;000 -41120;HU Hungary;BM TG2167;213.181.208.141;42100;002 -67939;IT C4FM LAZIO;773RadioGroup;93.186.255.126;42000;000 -30483;IT C4FM Lodi;Lombardia;213.45.29.230;42000;001 -19437;IT C4FM Piemonte;DSP Italy;94.177.173.53;42000;005 -67411;IT Zona 4;EmiliaRomagna;212.84.32.29;42000;001 -25383;JP JAPAN;Fusion Japan;202.241.175.133;42000;000 -54889;K4MKH-YSF;K4MKH YSF FL;73.224.178.196;42000;000 -96455;NL Central;Centraal NL;90.145.156.196;42000;001 -85875;NL Fusion Almere;Flevoland;84.86.62.38;42000;020 -38627;NL YSF444;Dutch Refl.;85.214.69.145;42000;004 -56254;NO YSF006;Norway;80.89.46.242;42000;001 +60786;FR F1ZLJ (95);Val dOise-ARAM;82.236.81.19;42000;002 +86886;FR Room-ZIT;Room F1ZIT;151.80.143.185;42002;008 +39510;FR wiresxfrance;Wires-X-France;151.80.143.185;42000;000 +83665;FR YSF-Alpes;Rhone-Alpes;217.182.66.229;42000;000 +60284;FR YSF-Alsace;ALS(F) ROOM;91.121.136.94;42000;002 +19531;FR YSF-Bretagne;Bretagne;78.206.208.208;42000;000 +13844;FR YSF-Cappelle;YSF Room F1ZKY;92.188.0.108;42000;002 +58617;FR YSF-France;Fusion France;87.98.132.205;42000;023 +91713;FR YSF-Limouzi;C4FM Limousin;88.174.140.210;42000;000 +46353;FR YSF-Nord;Nord;79.137.74.24;42000;003 +33751;FUSION-ITALY;Italy YSFR;188.213.173.69;42000;001 +91767;GB Fusion Kernow;Fusion SW UK;91.121.101.163;43000;002 +97576;GB N.Ireland;YSF N.Ireland;91.121.101.163;42500;004 +76849;GR YSF202;Fusion Greece;144.76.101.219;42000;006 +25419;Guatemala;CentOS7;74.208.88.137;42000;003 +47247;HB C4FM Basel;CISAR Basel;212.237.33.114;42000;002 +62928;HBLINK EA5GVK;HBLINK EA5GVK;84.127.124.188;42000;000 +98367;HK WTT YSF;No bridge;218.255.238.138;42006;004 +41120;HU Hungary;BM TG2167;213.181.208.141;42100;001 +04251;IE YSF Ireland;Fusion <> DMR;87.44.19.111;42000;011 +94264;IT C4FM ENNA;HAMRADIOENNA #;94.176.6.45;42000;000 +67939;IT C4FM LAZIO;773RadioGroup;93.186.255.126;42000;002 +30483;IT C4FM Lodi;Lombardia;79.54.231.198;42000;002 +51231;IT C4FM NORD;ITALY-NORD;78.47.154.19;42000;006 +19437;IT C4FM Piemonte;DSP Italy;94.177.173.53;42000;004 +64159;IT ITALY-FREE;c4fm bridge;37.187.106.175;42000;003 +82044;IT YSFROOM-ITALY;WIRES-X ITALY;94.177.187.40;42000;012 +67411;IT Zona 4;EmiliaRomagna;212.84.32.29;42000;000 +25383;JP JAPAN;Fusion Japan;202.241.175.133;42000;002 +96455;NL Central;Centraal NL;90.145.156.196;42000;004 +85875;NL Fusion Almere;Flevoland;84.86.62.38;42000;018 +73238;NL Noord;test reflector;44.137.87.82;42000;001 +63539;NL Oost;test reflector;44.137.87.83;42000;002 +73443;NL PI1DAF;Multi Repeater;77.174.30.155;42000;003 +66644;NL YSF amprnet;ampr reflector;44.137.33.52;42000;000 +38627;NL YSF444;Dutch Refl.;188.68.37.51;42000;003 +56254;NO YSF006;Norway;80.89.46.242;42000;009 +88973;NZ NZ750;XLX750 NZ;210.55.201.126;42000;002 +49480;NZ NZXLX;XLX626;202.137.244.157;42000;002 +46031;NZ ZL2VH;ZL2VH YSF;123.255.47.67;42000;002 +37761;OklahomaLink;OklahomaLink;70.189.115.214;42000;004 00001;Parrot;Parrot;213.202.229.15;42020;000 -25393;PL 4280;YSF/DMR/DCS02G;5.226.117.25;42031;000 -98564;PL EmCom;EmCom TG260023;91.188.125.199;42023;001 -29114;PL POLAND;POLAND-ROOM;91.188.125.199;42025;006 -38274;PL Poland 21;DMR TG260021;91.188.125.199;42021;001 -04463;PL Poland 22;DMR TG260022;91.188.125.199;42022;001 -78099;PL SR8FWD;Wlodawa WiresX;5.226.117.25;42030;000 -00113;PL SR8LU;Lublin;91.188.125.199;42028;001 -61506;PL SR8UD;Ustrzyki;5.226.117.25;42032;000 -54644;PL SR8UWD;Wlodawa;91.188.125.199;42027;001 -80986;PL YSF260;DMR TG260;91.188.125.199;42026;001 -09948;PT YSF009;C4FM-Portugal;109.71.44.237;42000;001 +25393;PL 4280;YSF/DMR/DCS132;94.246.175.66;42031;002 +98564;PL EmCom;EmCom TG260023;195.26.76.59;42023;001 +29114;PL POLAND;POLAND WiresX;94.246.175.66;42025;005 +38274;PL Poland 21;DMR TG260021;195.26.76.59;42021;001 +04463;PL Poland 22;DMR TG260022;195.26.76.59;42022;001 +55546;PL Silesia;Poland Silesia;188.116.7.66;42001;000 +11533;PL SR8DMR;RTCN Chotycze;94.246.175.66;42029;001 +78099;PL SR8FWD;Wlodawa WiresX;94.246.175.66;42030;001 +91407;PL SR8LUF;Lublin;94.246.175.66;42028;001 +61506;PL SR8UD;Ustrzyki;94.246.175.66;42032;000 +54644;PL SR8UWD;Wlodawa YSF;94.246.175.66;42027;001 +80986;PL YSF260;BM TG260;94.246.175.66;42035;001 +09948;PT YSF009;C4FM-Portugal;109.71.44.237;42000;005 +89355;R.E.E.C.;R.E.E.C.;5.135.137.65;42000;000 13131;ref.c4fm.se;ref.c4fm.se;176.10.140.161;42000;004 -51586;RO YSF DMR;#29065 <-> TG2;77.81.104.26;42005;001 -99447;RO YSF226;#99447;77.81.104.26;42000;003 -40208;SC Scotland;Scottish YSF;13.69.14.204;42000;004 -73331;SE YSF699;Tekniksnack.se;37.123.186.251;42000;002 -07237;TechTalk24;Engineers talk;91.188.125.199;42024;001 +23116;RO MULTIMODE;BM TG2260;94.176.6.37;42005;002 +99447;RO YSF226;BM TG226;94.176.6.37;42000;004 +00229;RO YSF<->Wires-X;C4FM Reflector;94.176.6.37;42001;002 +40208;SC Scotland;Scottish YSF;13.69.14.204;42000;008 +43699;SE SK7ES;SK7ES Fusion;44.140.236.22;42000;000 +77010;SE SW-Sweden;C4FM;46.236.122.101;52000;000 +07237;TechTalk24;Engineers talk;195.26.76.59;42024;002 +43513;TROJMIASTO;Poland Tricity;195.140.190.58;42000;001 30743;TW HAMTALK;C4FM @HAMTALK;118.150.164.96;42000;001 00325;TW YSF886;C4FM Taiwan;118.163.103.178;42000;000 -13201;UK DVMEGA;DVMEGA CHAT;90.145.156.196;42001;009 -83087;UK_YSF_BM_UK;UK_Ref_DN_ONLY;91.121.101.163;42000;002 -84105;US East PA;MMDVM System;173.49.20.45;42005;001 -02912;US Nationwide;United States;174.36.222.36;42000;002 -53594;US Ohio;Ohio;162.243.74.151;42000;000 +13201;UK DVMEGA;DVMEGA CHAT;212.237.34.32;42000;013 +93019;UK DVMEGA SH;DVMEGA CHAT SH;212.237.18.27;42000;002 +83087;UK_YSF_BM_UK;UK_Ref_DN_ONLY;91.121.101.163;42000;018 +21988;US AggielandLink;Aggieland Link;71.252.210.227;42000;003 +22647;US BM TG 31254;Carolina Link;52.3.47.55;42000;005 +51512;US BM TG 3137;North Carolina;52.3.47.55;42001;001 +74185;US BM-TG3139;DMR-313960-To-;52.54.69.145;42000;003 +49235;US CKRG;Central Kansas;198.211.109.207;42000;002 +39906;US COLORADO-LINK;Colorado Link;13.78.187.50;42000;006 +84105;US East PA;MMDVM System;173.49.20.45;42005;000 +04162;US GLOBAL DX;Global DX;206.72.198.26;42000;002 +30725;US K7EVR YSF;EVAR Mesa,AZ;72.201.150.71;42000;001 +02912;US Nationwide;United States;174.36.222.36;42000;016 +53594;US Ohio;Ohio;162.243.74.151;42000;001 +62554;US Texas-Nexus;Texas-Nexus;104.2.186.135;42000;022 +80767;US TGIF-BM 31665;US TGIF-BM 316;162.248.92.62;42000;013 +98899;US WolfDen;Massachusetts;100.0.26.120;42000;002 90943;US YSF 858;YSF SDCA-NZ6D;104.236.156.191;42000;001 -91768;US YSF082 NYC;KARG & NB2O;108.21.232.23;42000;001 -20584;US YSF616 WMTG;WMTG Fusion;44.103.39.6;42000;000 -12224;US-YSF-NE;NEW-ENGLAND;54.144.216.63;42000;003 -39117;US-YSF587MiFL;YSF-QNetBridge;96.47.239.135;42000;002 -24519;YSF-EA5 SPAIN;Zona EA5;95.39.140.240;42105;005 +08033;US YSF002;KingsOfDigital;52.10.253.1;42000;001 +91768;US YSF082 NYC;KARG & NB2O;108.21.232.23;42000;002 +23864;US YSF310;K6KD;64.137.191.209;42000;001 +96429;US-KansasLink;Kansas C4FM Re;72.205.226.24;42000;006 +87531;US-QuadNetATL;QuadNet-BM;107.191.121.105;42000;001 +74247;US-RepeaterBook;DMR TG 31419;69.71.127.9;42000;002 +12224;US-YSF-NE;NEW-ENGLAND;54.144.216.63;42000;009 +33386;US-YSF570;NEPA Fusion Sy;104.128.230.153;42000;000 +88051;US-YSF587NYS;YSF-QNetBridge;216.155.157.11;42000;002 +41577;YSF YO W;Fusion Romania;89.122.215.236;42000;003 +91559;YSF-BRAZIL;C4FM-BRAZIL;200.231.36.174;42000;004 +24519;YSF-EA5 SPAIN;Zona EA5;84.127.124.188;42105;006 93029;YSF004 MI5 SW2;Crossconnect t;44.103.34.3;42000;001 -55937;YSF017;YSFLatino 914;190.15.171.186;42000;003 -90839;YSF071 South Kor;Fusion C4FM;211.60.41.185;42000;001 +65576;YSF937;Guri, South Ko;1.240.221.206;42000;000 diff --git a/YSFParrot/YSFParrot.cpp b/YSFParrot/YSFParrot.cpp index 7939215..568fb12 100644 --- a/YSFParrot/YSFParrot.cpp +++ b/YSFParrot/YSFParrot.cpp @@ -32,16 +32,22 @@ int main(int argc, char** argv) { if (argc == 1) { - ::fprintf(stderr, "Usage: YSFParrot [-d|--debug] \n"); + ::fprintf(stderr, "Usage: YSFParrot [-d|--debug] [-n|--nolog] \n"); return 1; } - unsigned int n = 1U; + int n = 1U; bool debug = false; - if (::strcmp(argv[1], "-d") == 0 || ::strcmp(argv[1], "--debug") == 0) { - debug = true; - n = 2U; + bool log = true; + + for (; n < argc-1; n++) { + if (::strcmp(argv[n], "-d") == 0 || ::strcmp(argv[n], "--debug") == 0) { + debug = true; + } + if (::strcmp(argv[n], "-n") == 0 || ::strcmp(argv[n], "--nolog") == 0) { + log = false; + } } unsigned int port = ::atoi(argv[n]); @@ -50,15 +56,16 @@ int main(int argc, char** argv) return 1; } - CYSFParrot parrot(port, debug); + CYSFParrot parrot(port, debug, log); parrot.run(); return 0; } -CYSFParrot::CYSFParrot(unsigned int port, bool debug) : +CYSFParrot::CYSFParrot(unsigned int port, bool debug, bool log) : m_port(port), -m_debug(debug) +m_debug(debug), +m_log(log) { } @@ -68,12 +75,19 @@ CYSFParrot::~CYSFParrot() void CYSFParrot::run() { - bool ret = ::LogInitialise(".", "YSFParrot", m_debug ? 1U : 2U, m_debug ? 1U : 2U); + int fileLevel = 0U; + if (m_log) { + fileLevel = m_debug ? 1U : 2U; + } + bool ret = ::LogInitialise(".", "YSFParrot", fileLevel, m_debug ? 1U : 2U); if (!ret) { ::fprintf(stderr, "YSFParrot: unable to open the log file\n"); return; } + LogInfo("Debug: %s", m_debug ? "enabled" : "disabled"); + LogInfo("Logging to file: %s", m_log ? "enabled" : "disabled"); + CParrot parrot(180U); CNetwork network(m_port); diff --git a/YSFParrot/YSFParrot.h b/YSFParrot/YSFParrot.h index eb11476..03f2b47 100644 --- a/YSFParrot/YSFParrot.h +++ b/YSFParrot/YSFParrot.h @@ -22,7 +22,7 @@ class CYSFParrot { public: - CYSFParrot(unsigned int port, bool debug); + CYSFParrot(unsigned int port, bool debug, bool log); ~CYSFParrot(); void run(); @@ -30,6 +30,7 @@ public: private: unsigned int m_port; bool m_debug; + bool m_log; }; #endif diff --git a/YSFParrot/YSFParrot.vcxproj b/YSFParrot/YSFParrot.vcxproj index 21bf7d3..b4da17c 100644 --- a/YSFParrot/YSFParrot.vcxproj +++ b/YSFParrot/YSFParrot.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,32 +22,32 @@ {D3BBE5EC-91F7-457B-B782-B616B918708F} Win32Proj YSFParrot - 8.1 + 10.0.15063.0 Application true - v140 + v141 Unicode Application false - v140 + v141 true Unicode Application true - v140 + v141 Unicode Application false - v140 + v141 true Unicode @@ -87,7 +87,7 @@ Level3 Disabled - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS Console @@ -101,7 +101,7 @@ Level3 Disabled - _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS Console @@ -117,7 +117,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS Console @@ -135,7 +135,7 @@ MaxSpeed true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS Console diff --git a/YSFReflector/YSFReflector.vcxproj b/YSFReflector/YSFReflector.vcxproj index a4acc04..9f1f848 100644 --- a/YSFReflector/YSFReflector.vcxproj +++ b/YSFReflector/YSFReflector.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,32 +22,32 @@ {317D87F1-3485-4739-9F94-A07738B8E19D} Win32Proj YSFReflector - 8.1 + 10.0.15063.0 Application true - v140 + v141 Unicode Application false - v140 + v141 true Unicode Application true - v140 + v141 Unicode Application false - v140 + v141 true Unicode