diff --git a/Makefile b/Makefile index 8337006..92982b1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SUBDIRS = DGIdGateway YSFGateway YSFParrot YSFReflector +SUBDIRS = DGIdGateway YSFGateway YSFParrot CLEANDIRS = $(SUBDIRS:%=clean-%) INSTALLDIRS = $(SUBDIRS:%=install-%) diff --git a/README.md b/README.md index ebe457d..7520d68 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,7 @@ The YSF Gateway allows for use of Yaesu Wires-X commands from the radio to contr The DG-ID Gateway allows the use of the DG-ID setting on the radio to control access to the different System Fusion network systems. It optionally sends System Fusion GPS information to aprs.fi. -The Reflector retransmits any received System Fusion data to other MMDVM Hosts or Gateways logged into the reflector at the time. It also provides status information to potential clients. - -The Gateways and the Reflector have ini files that contain the parameters for running the software. The filename of the ini file is passed as a parameter on the command line. The Parrot takes the UDP port number to listen on as an argument. +The Gateways have ini files that contain the parameters for running the software. The filename of the ini file is passed as a parameter on the command line. The Parrot takes the UDP port number to listen on as an argument. The MMDVM .ini file should have the IP address and port number of the client in the [System Fusion Network] settings. diff --git a/YSFClients.sln b/YSFClients.sln index 409feda..acd391f 100644 --- a/YSFClients.sln +++ b/YSFClients.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.30406.217 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YSFParrot", "YSFParrot\YSFParrot.vcxproj", "{D3BBE5EC-91F7-457B-B782-B616B918708F}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YSFReflector", "YSFReflector\YSFReflector.vcxproj", "{317D87F1-3485-4739-9F94-A07738B8E19D}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YSFGateway", "YSFGateway\YSFGateway.vcxproj", "{4F82857B-D2CC-48DC-91A8-6275BDD3081B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DGIdGateway", "DGIdGateway\DGIdGateway.vcxproj", "{1A4724B0-257E-45E9-943D-EABC56A1027E}" @@ -27,14 +25,6 @@ Global {D3BBE5EC-91F7-457B-B782-B616B918708F}.Release|x64.Build.0 = Release|x64 {D3BBE5EC-91F7-457B-B782-B616B918708F}.Release|x86.ActiveCfg = Release|Win32 {D3BBE5EC-91F7-457B-B782-B616B918708F}.Release|x86.Build.0 = Release|Win32 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Debug|x64.ActiveCfg = Debug|x64 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Debug|x64.Build.0 = Debug|x64 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Debug|x86.ActiveCfg = Debug|Win32 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Debug|x86.Build.0 = Debug|Win32 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Release|x64.ActiveCfg = Release|x64 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Release|x64.Build.0 = Release|x64 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Release|x86.ActiveCfg = Release|Win32 - {317D87F1-3485-4739-9F94-A07738B8E19D}.Release|x86.Build.0 = Release|Win32 {4F82857B-D2CC-48DC-91A8-6275BDD3081B}.Debug|x64.ActiveCfg = Debug|x64 {4F82857B-D2CC-48DC-91A8-6275BDD3081B}.Debug|x64.Build.0 = Debug|x64 {4F82857B-D2CC-48DC-91A8-6275BDD3081B}.Debug|x86.ActiveCfg = Debug|Win32 diff --git a/YSFReflector/BlockList.cpp b/YSFReflector/BlockList.cpp deleted file mode 100644 index 1f2605a..0000000 --- a/YSFReflector/BlockList.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2021 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. - */ - -#include "BlockList.h" -#include "YSFDefines.h" -#include "Log.h" - -#include - -#include -#include -#include - -const int BUFFER_SIZE = 500; - -CBlockList::CBlockList(const std::string& file, unsigned int time) : -m_file(file), -m_time(time), -m_callsigns(), -m_timer(1000U, time * 60U), -m_checksum(0U) -{ -} - -CBlockList::~CBlockList() -{ -} - -bool CBlockList::start() -{ - loadFile(); - - m_timer.start(); - - return true; -} - -bool CBlockList::check(const unsigned char* callsign) const -{ - assert(callsign != NULL); - - if (m_callsigns.empty()) - return false; - - std::string call = std::string((char*)callsign, YSF_CALLSIGN_LENGTH); - std::for_each(call.begin(), call.end(), [](char& c) { - c = std::toupper(c); - }); - - for (std::vector::const_iterator it = m_callsigns.cbegin(); it != m_callsigns.cend(); ++it) { - const std::string blocked = *it; - if (call.find(blocked) != std::string::npos) - return true; - } - - return false; -} - -void CBlockList::clock(unsigned int ms) -{ - m_timer.clock(ms); - - if (m_timer.isRunning() && m_timer.hasExpired()) { - loadFile(); - m_timer.start(); - } -} - -bool CBlockList::loadFile() -{ - FILE* fp = ::fopen(m_file.c_str(), "rt"); - if (fp == NULL) { - if (!m_callsigns.empty()) { - m_callsigns.clear(); - LogInfo("Loaded %u callsigns from the block list", m_callsigns.size()); - } - return false; - } - - char buffer[BUFFER_SIZE]; - - // First perform the checksum (Fletcher 16) - uint16_t sum1 = 0U; - uint16_t sum2 = 0U; - while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) { - for (char* p = buffer; *p != '\0'; p++) { - sum1 = (sum1 + uint8_t(*p)) % 255U; - sum2 = (sum2 + sum1) % 255U; - } - } - - uint16_t checksum = (sum2 << 8) | sum1; - if (checksum == m_checksum) { - ::fclose(fp); - return false; - } - - m_checksum = checksum; - - // Rewind the file - ::fseek(fp, 0L, SEEK_SET); - - // Read the callsigns into the array - m_callsigns.clear(); - - while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) { - char* p; - if ((p = ::strchr(buffer, '\n')) != NULL) - *p = '\0'; - if ((p = ::strchr(buffer, '\r')) != NULL) - *p = '\0'; - - if (::strlen(buffer) > 0U) { - std::string callsign = std::string(buffer); - - std::for_each(callsign.begin(), callsign.end(), [](char& c) { - c = std::toupper(c); - }); - - m_callsigns.push_back(callsign); - } - } - - ::fclose(fp); - - LogInfo("Loaded %u callsigns from the block list", m_callsigns.size()); - - return true; -} diff --git a/YSFReflector/BlockList.h b/YSFReflector/BlockList.h deleted file mode 100644 index 3ddbcbb..0000000 --- a/YSFReflector/BlockList.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2021 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. - */ - -#if !defined(BLOCKLIST_H) -#define BLOCKLIST_H - -#include "Timer.h" - -#include -#include -#include - -class CBlockList -{ -public: - CBlockList(const std::string& file, unsigned int time); - ~CBlockList(); - - bool start(); - - bool check(const unsigned char* callsign) const; - - void clock(unsigned int ms); - -private: - std::string m_file; - unsigned int m_time; - std::vector m_callsigns; - CTimer m_timer; - uint16_t m_checksum; - - bool loadFile(); -}; - -#endif diff --git a/YSFReflector/Conf.cpp b/YSFReflector/Conf.cpp deleted file mode 100644 index 773d176..0000000 --- a/YSFReflector/Conf.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2015,2016,2020,2021 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. - */ - -#include "Conf.h" -#include "Log.h" - -#include -#include -#include -#include - -const int BUFFER_SIZE = 500; - -enum SECTION { - SECTION_NONE, - SECTION_GENERAL, - SECTION_INFO, - SECTION_LOG, - SECTION_NETWORK, - SECTION_BLOCKLIST -}; - -CConf::CConf(const std::string& file) : -m_file(file), -m_daemon(false), -m_id(0U), -m_name(), -m_description(), -m_logDisplayLevel(0U), -m_logFileLevel(0U), -m_logFilePath(), -m_logFileRoot(), -m_logFileRotate(true), -m_networkPort(0U), -m_networkDebug(false), -m_blockListFile(), -m_blockListTime(5U) -{ -} - -CConf::~CConf() -{ -} - -bool CConf::read() -{ - FILE* fp = ::fopen(m_file.c_str(), "rt"); - if (fp == NULL) { - ::fprintf(stderr, "Couldn't open the .ini file - %s\n", m_file.c_str()); - return false; - } - - SECTION section = SECTION_NONE; - - char buffer[BUFFER_SIZE]; - while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) { - if (buffer[0U] == '#') - continue; - - if (buffer[0U] == '[') { - if (::strncmp(buffer, "[General]", 9U) == 0) - section = SECTION_GENERAL; - else if (::strncmp(buffer, "[Info]", 6U) == 0) - section = SECTION_INFO; - else if (::strncmp(buffer, "[Log]", 5U) == 0) - section = SECTION_LOG; - else if (::strncmp(buffer, "[Network]", 9U) == 0) - section = SECTION_NETWORK; - else if (::strncmp(buffer, "[Block List]", 12U) == 0) - section = SECTION_BLOCKLIST; - else - section = SECTION_NONE; - - continue; - } - - char* key = ::strtok(buffer, " \t=\r\n"); - if (key == NULL) - continue; - - char* value = ::strtok(NULL, "\r\n"); - if (value == NULL) - continue; - - // Remove quotes from the value - size_t len = ::strlen(value); - if (len > 1U && *value == '"' && value[len - 1U] == '"') { - value[len - 1U] = '\0'; - value++; - } else { - char *p; - - // if value is not quoted, remove after # (to make comment) - if ((p = strchr(value, '#')) != NULL) - *p = '\0'; - - // remove trailing tab/space - for (p = value + strlen(value) - 1U; p >= value && (*p == '\t' || *p == ' '); p--) - *p = '\0'; - } - - if (section == SECTION_GENERAL) { - if (::strcmp(key, "Daemon") == 0) - m_daemon = ::atoi(value) == 1; - } else if (section == SECTION_INFO) { - if (::strcmp(key, "Id") == 0) - m_id = (unsigned int)::atoi(value); - else if (::strcmp(key, "Name") == 0) - m_name = value; - else if (::strcmp(key, "Description") == 0) - m_description = value; - } else if (section == SECTION_LOG) { - if (::strcmp(key, "FilePath") == 0) - m_logFilePath = value; - else if (::strcmp(key, "FileRoot") == 0) - m_logFileRoot = value; - else if (::strcmp(key, "FileLevel") == 0) - m_logFileLevel = (unsigned int)::atoi(value); - else if (::strcmp(key, "DisplayLevel") == 0) - m_logDisplayLevel = (unsigned int)::atoi(value); - else if (::strcmp(key, "FileRotate") == 0) - m_logFileRotate = ::atoi(value) == 1; - } else if (section == SECTION_NETWORK) { - if (::strcmp(key, "Port") == 0) - m_networkPort = (unsigned short)::atoi(value); - else if (::strcmp(key, "Debug") == 0) - m_networkDebug = ::atoi(value) == 1; - } else if (section == SECTION_BLOCKLIST) { - if (::strcmp(key, "File") == 0) - m_blockListFile = value; - else if (::strcmp(key, "Time") == 0) - m_blockListTime = (unsigned int)::atoi(value); - } - } - - ::fclose(fp); - - return true; -} - -bool CConf::getDaemon() const -{ - return m_daemon; -} - -unsigned int CConf::getId() const -{ - return m_id; -} - -std::string CConf::getName() const -{ - return m_name; -} - -std::string CConf::getDescription() const -{ - return m_description; -} - -unsigned int CConf::getLogDisplayLevel() const -{ - return m_logDisplayLevel; -} - -unsigned int CConf::getLogFileLevel() const -{ - return m_logFileLevel; -} - -std::string CConf::getLogFilePath() const -{ - return m_logFilePath; -} - -std::string CConf::getLogFileRoot() const -{ - return m_logFileRoot; -} - -bool CConf::getLogFileRotate() const -{ - return m_logFileRotate; -} - -unsigned short CConf::getNetworkPort() const -{ - return m_networkPort; -} - -bool CConf::getNetworkDebug() const -{ - return m_networkDebug; -} - -std::string CConf::getBlockListFile() const -{ - return m_blockListFile; -} - -unsigned int CConf::getBlockListTime() const -{ - return m_blockListTime; -} diff --git a/YSFReflector/Conf.h b/YSFReflector/Conf.h deleted file mode 100644 index 0922a8d..0000000 --- a/YSFReflector/Conf.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2015,2016,2020,2021 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. - */ - -#if !defined(CONF_H) -#define CONF_H - -#include -#include - -class CConf -{ -public: - CConf(const std::string& file); - ~CConf(); - - bool read(); - - // The General section - bool getDaemon() const; - - // The Info section - unsigned int getId() const; - std::string getName() const; - std::string getDescription() const; - - // The Log section - unsigned int getLogDisplayLevel() const; - unsigned int getLogFileLevel() const; - std::string getLogFilePath() const; - std::string getLogFileRoot() const; - bool getLogFileRotate() const; - - // The Network section - unsigned short getNetworkPort() const; - bool getNetworkDebug() const; - - // The Block List section - std::string getBlockListFile() const; - unsigned int getBlockListTime() const; - -private: - std::string m_file; - bool m_daemon; - - unsigned int m_id; - std::string m_name; - std::string m_description; - - unsigned int m_logDisplayLevel; - unsigned int m_logFileLevel; - std::string m_logFilePath; - std::string m_logFileRoot; - bool m_logFileRotate; - - unsigned short m_networkPort; - bool m_networkDebug; - - std::string m_blockListFile; - unsigned int m_blockListTime; -}; - -#endif diff --git a/YSFReflector/Log.cpp b/YSFReflector/Log.cpp deleted file mode 100644 index 752601e..0000000 --- a/YSFReflector/Log.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2015,2016,2020 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. - */ - -#include "Log.h" - -#if defined(_WIN32) || defined(_WIN64) -#include -#else -#include -#include -#endif - -#include -#include -#include -#include -#include -#include - -static unsigned int m_fileLevel = 2U; -static std::string m_filePath; -static std::string m_fileRoot; -static bool m_fileRotate = true; - -static FILE* m_fpLog = NULL; -static bool m_daemon = false; - -static unsigned int m_displayLevel = 2U; - -static struct tm m_tm; - -static char LEVELS[] = " DMIWEF"; - -static bool logOpenRotate() -{ - bool status = false; - - if (m_fileLevel == 0U) - return true; - - time_t now; - ::time(&now); - - struct tm* tm = ::gmtime(&now); - - if (tm->tm_mday == m_tm.tm_mday && tm->tm_mon == m_tm.tm_mon && tm->tm_year == m_tm.tm_year) { - if (m_fpLog != NULL) - return true; - } else { - if (m_fpLog != NULL) - ::fclose(m_fpLog); - } - - char filename[200U]; -#if defined(_WIN32) || defined(_WIN64) - ::sprintf(filename, "%s\\%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); -#else - ::sprintf(filename, "%s/%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); -#endif - - if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) { - status = true; - -#if !defined(_WIN32) && !defined(_WIN64) - if (m_daemon) - dup2(fileno(m_fpLog), fileno(stderr)); -#endif - } - - m_tm = *tm; - - return status; -} - -static bool logOpenNoRotate() -{ - bool status = false; - - if (m_fileLevel == 0U) - return true; - - if (m_fpLog != NULL) - return true; - - char filename[200U]; -#if defined(_WIN32) || defined(_WIN64) - ::sprintf(filename, "%s\\%s.log", m_filePath.c_str(), m_fileRoot.c_str()); -#else - ::sprintf(filename, "%s/%s.log", m_filePath.c_str(), m_fileRoot.c_str()); -#endif - - if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) { - status = true; - -#if !defined(_WIN32) && !defined(_WIN64) - if (m_daemon) - dup2(fileno(m_fpLog), fileno(stderr)); -#endif - } - - return status; -} - -bool LogOpen() -{ - if (m_fileRotate) - return logOpenRotate(); - else - return logOpenNoRotate(); -} - -bool LogInitialise(bool daemon, const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel, bool rotate) -{ - m_filePath = filePath; - m_fileRoot = fileRoot; - m_fileLevel = fileLevel; - m_displayLevel = displayLevel; - m_daemon = daemon; - m_fileRotate = rotate; - - if (m_daemon) - m_displayLevel = 0U; - - return ::LogOpen(); -} - -void LogFinalise() -{ - if (m_fpLog != NULL) - ::fclose(m_fpLog); -} - -void Log(unsigned int level, const char* fmt, ...) -{ - assert(fmt != NULL); - - char buffer[501U]; -#if defined(_WIN32) || defined(_WIN64) - SYSTEMTIME st; - ::GetSystemTime(&st); - - ::sprintf(buffer, "%c: %04u-%02u-%02u %02u:%02u:%02u.%03u ", LEVELS[level], st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); -#else - struct timeval now; - ::gettimeofday(&now, NULL); - - struct tm* tm = ::gmtime(&now.tv_sec); - - ::sprintf(buffer, "%c: %04d-%02d-%02d %02d:%02d:%02d.%03lld ", LEVELS[level], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000LL); -#endif - - va_list vl; - va_start(vl, fmt); - - ::vsnprintf(buffer + ::strlen(buffer), 500, fmt, vl); - - va_end(vl); - - if (level >= m_fileLevel && m_fileLevel != 0U) { - bool ret = ::LogOpen(); - if (!ret) - return; - - ::fprintf(m_fpLog, "%s\n", buffer); - ::fflush(m_fpLog); - } - - if (level >= m_displayLevel && m_displayLevel != 0U) { - ::fprintf(stdout, "%s\n", buffer); - ::fflush(stdout); - } - - if (level == 6U) { // Fatal - ::fclose(m_fpLog); - exit(1); - } -} diff --git a/YSFReflector/Log.h b/YSFReflector/Log.h deleted file mode 100644 index ae95b60..0000000 --- a/YSFReflector/Log.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015,2016,2020 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. - */ - -#if !defined(LOG_H) -#define LOG_H - -#include - -#define LogDebug(fmt, ...) Log(1U, fmt, ##__VA_ARGS__) -#define LogMessage(fmt, ...) Log(2U, fmt, ##__VA_ARGS__) -#define LogInfo(fmt, ...) Log(3U, fmt, ##__VA_ARGS__) -#define LogWarning(fmt, ...) Log(4U, fmt, ##__VA_ARGS__) -#define LogError(fmt, ...) Log(5U, fmt, ##__VA_ARGS__) -#define LogFatal(fmt, ...) Log(6U, fmt, ##__VA_ARGS__) - -extern void Log(unsigned int level, const char* fmt, ...); - -extern bool LogInitialise(bool daemon, const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel, bool rotate); -extern void LogFinalise(); - -#endif diff --git a/YSFReflector/Makefile b/YSFReflector/Makefile deleted file mode 100644 index 076375a..0000000 --- a/YSFReflector/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -CC = cc -CXX = c++ -CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DUDP_SOCKET_MAX=2 -LIBS = -lpthread -LDFLAGS = -g - -OBJECTS = BlockList.o Conf.o Log.o Network.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o YSFReflector.o - -all: YSFReflector - -YSFReflector: $(OBJECTS) - $(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o YSFReflector - -%.o: %.cpp - $(CXX) $(CFLAGS) -c -o $@ $< - -YSFReflector.o: GitVersion.h FORCE - -.PHONY: GitVersion.h - -FORCE: - -install: - install -m 755 YSFReflector /usr/local/bin/ - -clean: - $(RM) YSFReflector *.o *.d *.bak *~ GitVersion.h - -# Export the current git version if the index file exists, else 000... -GitVersion.h: -ifneq ("$(wildcard ../.git/index)","") - echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@ -else - echo "const char *gitversion = \"0000000000000000000000000000000000000000\";" > $@ -endif diff --git a/YSFReflector/Network.cpp b/YSFReflector/Network.cpp deleted file mode 100644 index 394f1a2..0000000 --- a/YSFReflector/Network.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2009-2014,2016,2020 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. - */ - -#include "YSFDefines.h" -#include "Network.h" -#include "Utils.h" -#include "Log.h" - -#include -#include -#include - -CNetwork::CNetwork(unsigned short port, unsigned int id, const std::string& name, const std::string& description, bool debug) : -m_socket(), -m_port(port), -m_id(id), -m_name(name), -m_description(description), -m_callsign(), -m_debug(debug), -m_status(NULL) -{ - m_name.resize(16U, ' '); - m_description.resize(14U, ' '); - - m_status = new unsigned char[50U]; -} - -CNetwork::~CNetwork() -{ - delete[] m_status; -} - -bool CNetwork::open() -{ - LogInfo("Opening YSF network connection"); - - bool status = false; - unsigned int af[] = {AF_INET, AF_INET6}; - - for (unsigned int i = 0U; i < UDP_SOCKET_MAX && i < (sizeof(af) / sizeof(unsigned int)); i++) - status |= m_socket.open(i, af[i], "", m_port); - - return status; -} - -bool CNetwork::writeData(const unsigned char* data, const sockaddr_storage& addr, unsigned int addrLen) -{ - assert(data != NULL); - - if (m_debug) - CUtils::dump(1U, "YSF Network Data Sent", data, 155U); - - return m_socket.write(data, 155U, addr, addrLen); -} - -bool CNetwork::writePoll(const sockaddr_storage& addr, unsigned int addrLen) -{ - unsigned char buffer[20U]; - - buffer[0] = 'Y'; - buffer[1] = 'S'; - buffer[2] = 'F'; - buffer[3] = 'P'; - - buffer[4U] = 'R'; - buffer[5U] = 'E'; - buffer[6U] = 'F'; - buffer[7U] = 'L'; - buffer[8U] = 'E'; - buffer[9U] = 'C'; - buffer[10U] = 'T'; - buffer[11U] = 'O'; - buffer[12U] = 'R'; - buffer[13U] = ' '; - - if (m_debug) - CUtils::dump(1U, "YSF Network Poll Sent", buffer, 14U); - - return m_socket.write(buffer, 14U, addr, addrLen); -} - -unsigned int CNetwork::readData(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen) -{ - assert(data != NULL); - assert(length > 0U); - - int len = m_socket.read(data, length, addr, addrLen); - if (len <= 0) - return 0U; - - if (m_debug) - CUtils::dump(1U, "YSF Network Data Received", data, len); - - // Throw away any options messages - if (::memcmp(data, "YSFO", 4U) == 0) - return 0U; - - // Throw away any info messages - if (::memcmp(data, "YSFI", 4U) == 0) - return 0U; - - // Handle incoming status requests - if (::memcmp(data, "YSFS", 4U) == 0) { - m_socket.write(m_status, 42U, addr, addrLen); - return 0U; - } - - return len; -} - -void CNetwork::setCount(unsigned int count) -{ - if (count > 999U) - count = 999U; - - unsigned int hash = m_id; - - if (hash == 0U) { - for (unsigned int i = 0U; i < m_name.size(); i++) { - hash += m_name.at(i); - hash += (hash << 10); - hash ^= (hash >> 6); - } - - // Final avalanche - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - } - - ::sprintf((char*)m_status, "YSFS%05u%16.16s%14.14s%03u", hash % 100000U, m_name.c_str(), m_description.c_str(), count); -} - -void CNetwork::close() -{ - m_socket.close(); - - LogInfo("Closing YSF network connection"); -} diff --git a/YSFReflector/Network.h b/YSFReflector/Network.h deleted file mode 100644 index 52b301b..0000000 --- a/YSFReflector/Network.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2009-2014,2016,2020 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 Network_H -#define Network_H - -#include "YSFDefines.h" -#include "UDPSocket.h" -#include "Timer.h" - -#include -#include - -class CNetwork { -public: - CNetwork(unsigned short port, unsigned int id, const std::string& name, const std::string& description, bool debug); - ~CNetwork(); - - bool open(); - - bool writeData(const unsigned char* data, const sockaddr_storage& addr, unsigned int addrLen); - bool writePoll(const sockaddr_storage& addr, unsigned int addrLen); - - unsigned int readData(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen); - - void close(); - - void setCount(unsigned int count); - -private: - CUDPSocket m_socket; - unsigned short m_port; - unsigned int m_id; - std::string m_name; - std::string m_description; - std::string m_callsign; - bool m_debug; - unsigned char* m_status; -}; - -#endif - diff --git a/YSFReflector/StopWatch.cpp b/YSFReflector/StopWatch.cpp deleted file mode 100644 index 481241b..0000000 --- a/YSFReflector/StopWatch.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2015,2016,2018 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. - */ - -#include "StopWatch.h" - -#if defined(_WIN32) || defined(_WIN64) - -CStopWatch::CStopWatch() : -m_frequencyS(), -m_frequencyMS(), -m_start() -{ - ::QueryPerformanceFrequency(&m_frequencyS); - - m_frequencyMS.QuadPart = m_frequencyS.QuadPart / 1000ULL; -} - -CStopWatch::~CStopWatch() -{ -} - -unsigned long long CStopWatch::time() const -{ - LARGE_INTEGER now; - ::QueryPerformanceCounter(&now); - - return (unsigned long long)(now.QuadPart / m_frequencyMS.QuadPart); -} - -unsigned long long CStopWatch::start() -{ - ::QueryPerformanceCounter(&m_start); - - return (unsigned long long)(m_start.QuadPart / m_frequencyS.QuadPart); -} - -unsigned int CStopWatch::elapsed() -{ - LARGE_INTEGER now; - ::QueryPerformanceCounter(&now); - - LARGE_INTEGER temp; - temp.QuadPart = (now.QuadPart - m_start.QuadPart) * 1000; - - return (unsigned int)(temp.QuadPart / m_frequencyS.QuadPart); -} - -#else - -#include -#include - -CStopWatch::CStopWatch() : -m_startMS(0ULL) -{ -} - -CStopWatch::~CStopWatch() -{ -} - -unsigned long long CStopWatch::time() const -{ - struct timeval now; - ::gettimeofday(&now, NULL); - - return now.tv_sec * 1000ULL + now.tv_usec / 1000ULL; -} - -unsigned long long CStopWatch::start() -{ - struct timespec now; - ::clock_gettime(CLOCK_MONOTONIC, &now); - - m_startMS = now.tv_sec * 1000ULL + now.tv_nsec / 1000000ULL; - - return m_startMS; -} - -unsigned int CStopWatch::elapsed() -{ - struct timespec now; - ::clock_gettime(CLOCK_MONOTONIC, &now); - - unsigned long long nowMS = now.tv_sec * 1000ULL + now.tv_nsec / 1000000ULL; - - return nowMS - m_startMS; -} - -#endif diff --git a/YSFReflector/StopWatch.h b/YSFReflector/StopWatch.h deleted file mode 100644 index b628392..0000000 --- a/YSFReflector/StopWatch.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2015,2016,2018 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. - */ - -#if !defined(STOPWATCH_H) -#define STOPWATCH_H - -#if defined(_WIN32) || defined(_WIN64) -#include -#include -#else -#include -#endif - -class CStopWatch -{ -public: - CStopWatch(); - ~CStopWatch(); - - unsigned long long time() const; - - unsigned long long start(); - unsigned int elapsed(); - -private: -#if defined(_WIN32) || defined(_WIN64) - LARGE_INTEGER m_frequencyS; - LARGE_INTEGER m_frequencyMS; - LARGE_INTEGER m_start; -#else - unsigned long long m_startMS; -#endif -}; - -#endif diff --git a/YSFReflector/Thread.cpp b/YSFReflector/Thread.cpp deleted file mode 100644 index 6f76f5b..0000000 --- a/YSFReflector/Thread.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2015,2016,2020 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. - */ - -#include "Thread.h" - -#if defined(_WIN32) || defined(_WIN64) - -CThread::CThread() : -m_handle() -{ -} - -CThread::~CThread() -{ -} - -bool CThread::run() -{ - m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL); - - return m_handle != NULL; -} - - -void CThread::wait() -{ - ::WaitForSingleObject(m_handle, INFINITE); - - ::CloseHandle(m_handle); -} - - -DWORD CThread::helper(LPVOID arg) -{ - CThread* p = (CThread*)arg; - - p->entry(); - - return 0UL; -} - -void CThread::sleep(unsigned int ms) -{ - ::Sleep(ms); -} - -#else - -#include - -CThread::CThread() : -m_thread() -{ -} - -CThread::~CThread() -{ -} - -bool CThread::run() -{ - return ::pthread_create(&m_thread, NULL, helper, this) == 0; -} - - -void CThread::wait() -{ - ::pthread_join(m_thread, NULL); -} - - -void* CThread::helper(void* arg) -{ - CThread* p = (CThread*)arg; - - p->entry(); - - return NULL; -} - -void CThread::sleep(unsigned int ms) -{ - struct timespec ts; - - ts.tv_sec = ms / 1000U; - ts.tv_nsec = (ms % 1000U) * 1000000U; - - ::nanosleep(&ts, NULL); -} - -#endif - diff --git a/YSFReflector/Thread.h b/YSFReflector/Thread.h deleted file mode 100644 index 352d938..0000000 --- a/YSFReflector/Thread.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2015,2016 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. - */ - -#if !defined(THREAD_H) -#define THREAD_H - -#if defined(_WIN32) || defined(_WIN64) -#include -#else -#include -#endif - -class CThread -{ -public: - CThread(); - virtual ~CThread(); - - virtual bool run(); - - virtual void entry() = 0; - - virtual void wait(); - - static void sleep(unsigned int ms); - -private: -#if defined(_WIN32) || defined(_WIN64) - HANDLE m_handle; -#else - pthread_t m_thread; -#endif - -#if defined(_WIN32) || defined(_WIN64) - static DWORD __stdcall helper(LPVOID arg); -#else - static void* helper(void* arg); -#endif -}; - -#endif diff --git a/YSFReflector/Timer.cpp b/YSFReflector/Timer.cpp deleted file mode 100644 index 53956e4..0000000 --- a/YSFReflector/Timer.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2009,2010,2015 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. - */ - -#include "Timer.h" - -#include -#include - -CTimer::CTimer(unsigned int ticksPerSec, unsigned int secs, unsigned int msecs) : -m_ticksPerSec(ticksPerSec), -m_timeout(0U), -m_timer(0U) -{ - assert(ticksPerSec > 0U); - - if (secs > 0U || msecs > 0U) { - // m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U; - unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec; - m_timeout = (unsigned int)(temp / 1000ULL + 1ULL); - } -} - -CTimer::~CTimer() -{ -} - -void CTimer::setTimeout(unsigned int secs, unsigned int msecs) -{ - if (secs > 0U || msecs > 0U) { - // m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U; - unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec; - m_timeout = (unsigned int)(temp / 1000ULL + 1ULL); - } else { - m_timeout = 0U; - m_timer = 0U; - } -} - -unsigned int CTimer::getTimeout() const -{ - if (m_timeout == 0U) - return 0U; - - return (m_timeout - 1U) / m_ticksPerSec; -} - -unsigned int CTimer::getTimer() const -{ - if (m_timer == 0U) - return 0U; - - return (m_timer - 1U) / m_ticksPerSec; -} diff --git a/YSFReflector/Timer.h b/YSFReflector/Timer.h deleted file mode 100644 index 87d68f5..0000000 --- a/YSFReflector/Timer.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2009,2010,2011,2014 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 Timer_H -#define Timer_H - -class CTimer { -public: - CTimer(unsigned int ticksPerSec, unsigned int secs = 0U, unsigned int msecs = 0U); - ~CTimer(); - - void setTimeout(unsigned int secs, unsigned int msecs = 0U); - - unsigned int getTimeout() const; - unsigned int getTimer() const; - - unsigned int getRemaining() - { - if (m_timeout == 0U || m_timer == 0U) - return 0U; - - if (m_timer >= m_timeout) - return 0U; - - return (m_timeout - m_timer) / m_ticksPerSec; - } - - bool isRunning() - { - return m_timer > 0U; - } - - void start(unsigned int secs, unsigned int msecs = 0U) - { - setTimeout(secs, msecs); - - start(); - } - - void start() - { - if (m_timeout > 0U) - m_timer = 1U; - } - - void stop() - { - m_timer = 0U; - } - - bool hasExpired() - { - if (m_timeout == 0U || m_timer == 0U) - return false; - - if (m_timer >= m_timeout) - return true; - - return false; - } - - void clock(unsigned int ticks = 1U) - { - if (m_timer > 0U && m_timeout > 0U) - m_timer += ticks; - } - -private: - unsigned int m_ticksPerSec; - unsigned int m_timeout; - unsigned int m_timer; -}; - -#endif diff --git a/YSFReflector/UDPSocket.cpp b/YSFReflector/UDPSocket.cpp deleted file mode 100644 index d6aee95..0000000 --- a/YSFReflector/UDPSocket.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (C) 2006-2016,2020,2021 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. - */ - -#include "UDPSocket.h" - -#include - -#if !defined(_WIN32) && !defined(_WIN64) -#include -#include -#endif - -#if defined(HAVE_LOG_H) -#include "Log.h" -#else -#define LogError(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__) -#define LogInfo(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__) -#endif - -CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) : -m_address_save(address), -m_port_save(port), -m_counter(0U) -{ - for (int i = 0; i < UDP_SOCKET_MAX; i++) { - m_address[i] = ""; - m_port[i] = 0U; - m_af[i] = 0U; - m_fd[i] = -1; - } -} - -CUDPSocket::CUDPSocket(unsigned int port) : -m_address_save(), -m_port_save(port), -m_counter(0U) -{ - for (int i = 0; i < UDP_SOCKET_MAX; i++) { - m_address[i] = ""; - m_port[i] = 0U; - m_af[i] = 0U; - m_fd[i] = -1; - } -} - -CUDPSocket::~CUDPSocket() -{ -} - -void CUDPSocket::startup() -{ -#if defined(_WIN32) || defined(_WIN64) - WSAData data; - int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data); - if (wsaRet != 0) - LogError("Error from WSAStartup"); -#endif -} - -void CUDPSocket::shutdown() -{ -#if defined(_WIN32) || defined(_WIN64) - ::WSACleanup(); -#endif -} - -int CUDPSocket::lookup(const std::string& hostname, unsigned int port, sockaddr_storage& addr, unsigned int& address_length) -{ - struct addrinfo hints; - ::memset(&hints, 0, sizeof(hints)); - - return lookup(hostname, port, addr, address_length, hints); -} - -int CUDPSocket::lookup(const std::string& hostname, unsigned int port, sockaddr_storage& addr, unsigned int& address_length, struct addrinfo& hints) -{ - std::string portstr = std::to_string(port); - struct addrinfo *res; - - /* port is always digits, no needs to lookup service */ - hints.ai_flags |= AI_NUMERICSERV; - - int err = getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), portstr.c_str(), &hints, &res); - if (err != 0) { - sockaddr_in* paddr = (sockaddr_in*)&addr; - ::memset(paddr, 0x00U, address_length = sizeof(sockaddr_in)); - paddr->sin_family = AF_INET; - paddr->sin_port = htons(port); - paddr->sin_addr.s_addr = htonl(INADDR_NONE); - LogError("Cannot find address for host %s", hostname.c_str()); - return err; - } - - ::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen); - - freeaddrinfo(res); - - return 0; -} - -bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type) -{ - if (addr1.ss_family != addr2.ss_family) - return false; - - if (type == IMT_ADDRESS_AND_PORT) { - switch (addr1.ss_family) { - case AF_INET: - struct sockaddr_in *in_1, *in_2; - in_1 = (struct sockaddr_in*)&addr1; - in_2 = (struct sockaddr_in*)&addr2; - return (in_1->sin_addr.s_addr == in_2->sin_addr.s_addr) && (in_1->sin_port == in_2->sin_port); - case AF_INET6: - struct sockaddr_in6 *in6_1, *in6_2; - in6_1 = (struct sockaddr_in6*)&addr1; - in6_2 = (struct sockaddr_in6*)&addr2; - return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr) && (in6_1->sin6_port == in6_2->sin6_port); - default: - return false; - } - } else if (type == IMT_ADDRESS_ONLY) { - switch (addr1.ss_family) { - case AF_INET: - struct sockaddr_in *in_1, *in_2; - in_1 = (struct sockaddr_in*)&addr1; - in_2 = (struct sockaddr_in*)&addr2; - return in_1->sin_addr.s_addr == in_2->sin_addr.s_addr; - case AF_INET6: - struct sockaddr_in6 *in6_1, *in6_2; - in6_1 = (struct sockaddr_in6*)&addr1; - in6_2 = (struct sockaddr_in6*)&addr2; - return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr); - default: - return false; - } - } else { - return false; - } -} - -bool CUDPSocket::isNone(const sockaddr_storage& addr) -{ - struct sockaddr_in *in = (struct sockaddr_in *)&addr; - - return ((addr.ss_family == AF_INET) && (in->sin_addr.s_addr == htonl(INADDR_NONE))); -} - -char* CUDPSocket::display(const sockaddr_storage& addr, char* buffer, unsigned int length) -{ - assert(buffer != NULL); - assert(length > INET6_ADDRSTRLEN); - - switch (addr.ss_family) { - case AF_INET: { - struct sockaddr_in* in4 = (struct sockaddr_in*)&addr; - ::inet_ntop(AF_INET, &in4->sin_addr, buffer, length); - ::sprintf(buffer + ::strlen(buffer), ":%u", in4->sin_port); - } - break; - - case AF_INET6: { - struct sockaddr_in6* in6 = (struct sockaddr_in6*)&addr; - ::inet_ntop(AF_INET6, &in6->sin6_addr, buffer, length); - ::sprintf(buffer + ::strlen(buffer), ":%u", in6->sin6_port); - } - break; - - default: - ::strcpy(buffer, "Unknown"); - break; - } - - return buffer; -} - -bool CUDPSocket::open(const sockaddr_storage& address) -{ - return open(address.ss_family); -} - -bool CUDPSocket::open(unsigned int af) -{ - return open(0, af, m_address_save, m_port_save); -} - -bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned int port) -{ - sockaddr_storage addr; - unsigned int addrlen; - struct addrinfo hints; - - ::memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = af; - - /* to determine protocol family, call lookup() first. */ - int err = lookup(address, port, addr, addrlen, hints); - if (err != 0) { - LogError("The local address is invalid - %s", address.c_str()); - return false; - } - - close(index); - - int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0); - if (fd < 0) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Cannot create the UDP socket, err: %lu", ::GetLastError()); -#else - LogError("Cannot create the UDP socket, err: %d", errno); -#endif - return false; - } - - m_address[index] = address; - m_port[index] = port; - m_af[index] = addr.ss_family; - m_fd[index] = fd; - - if (port > 0U) { - int reuse = 1; - if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Cannot set the UDP socket option, err: %lu", ::GetLastError()); -#else - LogError("Cannot set the UDP socket option, err: %d", errno); -#endif - return false; - } - - if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Cannot bind the UDP address, err: %lu", ::GetLastError()); -#else - LogError("Cannot bind the UDP address, err: %d", errno); -#endif - return false; - } - - LogInfo("Opening UDP port on %u", port); - } - - return true; -} - -int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length) -{ - assert(buffer != NULL); - assert(length > 0U); - - // Check that the readfrom() won't block - int i, n; - struct pollfd pfd[UDP_SOCKET_MAX]; - for (i = n = 0; i < UDP_SOCKET_MAX; i++) { - if (m_fd[i] >= 0) { - pfd[n].fd = m_fd[i]; - pfd[n].events = POLLIN; - n++; - } - } - - // no socket descriptor to receive - if (n == 0) - return 0; - - // Return immediately -#if defined(_WIN32) || defined(_WIN64) - int ret = WSAPoll(pfd, n, 0); -#else - int ret = ::poll(pfd, n, 0); -#endif - if (ret < 0) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from UDP poll, err: %lu", ::GetLastError()); -#else - LogError("Error returned from UDP poll, err: %d", errno); -#endif - return -1; - } - - int index; - for (i = 0; i < n; i++) { - // round robin - index = (i + m_counter) % n; - if (pfd[index].revents & POLLIN) - break; - } - if (i == n) - return 0; - -#if defined(_WIN32) || defined(_WIN64) - int size = sizeof(sockaddr_storage); -#else - socklen_t size = sizeof(sockaddr_storage); -#endif - -#if defined(_WIN32) || defined(_WIN64) - int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size); -#else - ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size); -#endif - if (len <= 0) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from recvfrom, err: %lu", ::GetLastError()); -#else - LogError("Error returned from recvfrom, err: %d", errno); - - if (len == -1 && errno == ENOTSOCK) { - LogMessage("Re-opening UDP port on %u", m_port); - close(); - open(); - } -#endif - return -1; - } - - m_counter++; - address_length = size; - return len; -} - -bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length) -{ - assert(buffer != NULL); - assert(length > 0U); - - bool result = false; - - for (int i = 0; i < UDP_SOCKET_MAX; i++) { - if (m_fd[i] < 0 || m_af[i] != address.ss_family) - continue; - -#if defined(_WIN32) || defined(_WIN64) - int ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length); -#else - ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length); -#endif - - if (ret < 0) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from sendto, err: %lu", ::GetLastError()); -#else - LogError("Error returned from sendto, err: %d", errno); -#endif - } else { -#if defined(_WIN32) || defined(_WIN64) - if (ret == int(length)) - result = true; -#else - if (ret == ssize_t(length)) - result = true; -#endif - } - } - - return result; -} - -void CUDPSocket::close() -{ - for (unsigned int i = 0; i < UDP_SOCKET_MAX; i++) - close(i); -} - -void CUDPSocket::close(const unsigned int index) -{ - if ((index < UDP_SOCKET_MAX) && (m_fd[index] >= 0)) { -#if defined(_WIN32) || defined(_WIN64) - ::closesocket(m_fd[index]); -#else - ::close(m_fd[index]); -#endif - m_fd[index] = -1; - } -} diff --git a/YSFReflector/UDPSocket.h b/YSFReflector/UDPSocket.h deleted file mode 100644 index 003483b..0000000 --- a/YSFReflector/UDPSocket.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2009-2011,2013,2015,2016,2020 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 UDPSocket_H -#define UDPSocket_H - -#include - -#if !defined(_WIN32) && !defined(_WIN64) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -#if !defined(UDP_SOCKET_MAX) -#define UDP_SOCKET_MAX 1 -#endif - -enum IPMATCHTYPE { - IMT_ADDRESS_AND_PORT, - IMT_ADDRESS_ONLY -}; - -class CUDPSocket { -public: - CUDPSocket(const std::string& address, unsigned int port = 0U); - CUDPSocket(unsigned int port = 0U); - ~CUDPSocket(); - - bool open(unsigned int af = AF_UNSPEC); - bool open(const sockaddr_storage& address); - bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned int port); - - int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length); - bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length); - - void close(); - void close(const unsigned int index); - - static void startup(); - static void shutdown(); - - static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage& address, unsigned int& address_length); - static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints); - - static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT); - - static bool isNone(const sockaddr_storage& addr); - - static char* display(const sockaddr_storage& address, char* buffer, unsigned int length); - -private: - std::string m_address_save; - unsigned short m_port_save; - std::string m_address[UDP_SOCKET_MAX]; - unsigned short m_port[UDP_SOCKET_MAX]; - unsigned int m_af[UDP_SOCKET_MAX]; - int m_fd[UDP_SOCKET_MAX]; - unsigned int m_counter; -}; - -#endif diff --git a/YSFReflector/Utils.cpp b/YSFReflector/Utils.cpp deleted file mode 100644 index 49ded13..0000000 --- a/YSFReflector/Utils.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2009,2014,2015,2016 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; version 2 of the License. - * - * 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. - */ - -#include "Utils.h" -#include "Log.h" - -#include -#include - -void CUtils::dump(const std::string& title, const unsigned char* data, unsigned int length) -{ - assert(data != NULL); - - dump(2U, title, data, length); -} - -void CUtils::dump(int level, const std::string& title, const unsigned char* data, unsigned int length) -{ - assert(data != NULL); - - ::Log(level, "%s", title.c_str()); - - unsigned int offset = 0U; - - while (length > 0U) { - std::string output; - - unsigned int bytes = (length > 16U) ? 16U : length; - - for (unsigned i = 0U; i < bytes; i++) { - char temp[10U]; - ::sprintf(temp, "%02X ", data[offset + i]); - output += temp; - } - - for (unsigned int i = bytes; i < 16U; i++) - output += " "; - - output += " *"; - - for (unsigned i = 0U; i < bytes; i++) { - unsigned char c = data[offset + i]; - - if (::isprint(c)) - output += c; - else - output += '.'; - } - - output += '*'; - - ::Log(level, "%04X: %s", offset, output.c_str()); - - offset += 16U; - - if (length >= 16U) - length -= 16U; - else - length = 0U; - } -} - -void CUtils::dump(const std::string& title, const bool* bits, unsigned int length) -{ - assert(bits != NULL); - - dump(2U, title, bits, length); -} - -void CUtils::dump(int level, const std::string& title, const bool* bits, unsigned int length) -{ - assert(bits != NULL); - - unsigned char bytes[100U]; - unsigned int nBytes = 0U; - for (unsigned int n = 0U; n < length; n += 8U, nBytes++) - bitsToByteBE(bits + n, bytes[nBytes]); - - dump(level, title, bytes, nBytes); -} - -void CUtils::byteToBitsBE(unsigned char byte, bool* bits) -{ - assert(bits != NULL); - - bits[0U] = (byte & 0x80U) == 0x80U; - bits[1U] = (byte & 0x40U) == 0x40U; - bits[2U] = (byte & 0x20U) == 0x20U; - bits[3U] = (byte & 0x10U) == 0x10U; - bits[4U] = (byte & 0x08U) == 0x08U; - bits[5U] = (byte & 0x04U) == 0x04U; - bits[6U] = (byte & 0x02U) == 0x02U; - bits[7U] = (byte & 0x01U) == 0x01U; -} - -void CUtils::byteToBitsLE(unsigned char byte, bool* bits) -{ - assert(bits != NULL); - - bits[0U] = (byte & 0x01U) == 0x01U; - bits[1U] = (byte & 0x02U) == 0x02U; - bits[2U] = (byte & 0x04U) == 0x04U; - bits[3U] = (byte & 0x08U) == 0x08U; - bits[4U] = (byte & 0x10U) == 0x10U; - bits[5U] = (byte & 0x20U) == 0x20U; - bits[6U] = (byte & 0x40U) == 0x40U; - bits[7U] = (byte & 0x80U) == 0x80U; -} - -void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte) -{ - assert(bits != NULL); - - byte = bits[0U] ? 0x80U : 0x00U; - byte |= bits[1U] ? 0x40U : 0x00U; - byte |= bits[2U] ? 0x20U : 0x00U; - byte |= bits[3U] ? 0x10U : 0x00U; - byte |= bits[4U] ? 0x08U : 0x00U; - byte |= bits[5U] ? 0x04U : 0x00U; - byte |= bits[6U] ? 0x02U : 0x00U; - byte |= bits[7U] ? 0x01U : 0x00U; -} - -void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte) -{ - assert(bits != NULL); - - byte = bits[0U] ? 0x01U : 0x00U; - byte |= bits[1U] ? 0x02U : 0x00U; - byte |= bits[2U] ? 0x04U : 0x00U; - byte |= bits[3U] ? 0x08U : 0x00U; - byte |= bits[4U] ? 0x10U : 0x00U; - byte |= bits[5U] ? 0x20U : 0x00U; - byte |= bits[6U] ? 0x40U : 0x00U; - byte |= bits[7U] ? 0x80U : 0x00U; -} diff --git a/YSFReflector/Utils.h b/YSFReflector/Utils.h deleted file mode 100644 index ade28c0..0000000 --- a/YSFReflector/Utils.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2009,2014,2015 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; version 2 of the License. - * - * 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. - */ - -#ifndef Utils_H -#define Utils_H - -#include - -class CUtils { -public: - static void dump(const std::string& title, const unsigned char* data, unsigned int length); - static void dump(int level, const std::string& title, const unsigned char* data, unsigned int length); - - static void dump(const std::string& title, const bool* bits, unsigned int length); - static void dump(int level, const std::string& title, const bool* bits, unsigned int length); - - static void byteToBitsBE(unsigned char byte, bool* bits); - static void byteToBitsLE(unsigned char byte, bool* bits); - - static void bitsToByteBE(const bool* bits, unsigned char& byte); - static void bitsToByteLE(const bool* bits, unsigned char& byte); - -private: -}; - -#endif diff --git a/YSFReflector/Version.h b/YSFReflector/Version.h deleted file mode 100644 index ee48a9e..0000000 --- a/YSFReflector/Version.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2015,2016,2020,2021 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. - */ - -#if !defined(VERSION_H) -#define VERSION_H - -const char* VERSION = "20210824"; - -#endif diff --git a/YSFReflector/YSFDefines.h b/YSFReflector/YSFDefines.h deleted file mode 100644 index 348d1bc..0000000 --- a/YSFReflector/YSFDefines.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2015,2016 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. - */ - -#if !defined(YSFDefines_H) -#define YSFDefines_H - -const unsigned int YSF_FRAME_LENGTH_BYTES = 120U; - -const unsigned char YSF_SYNC_BYTES[] = {0xD4U, 0x71U, 0xC9U, 0x63U, 0x4DU}; -const unsigned int YSF_SYNC_LENGTH_BYTES = 5U; - -const unsigned int YSF_FICH_LENGTH_BYTES = 25U; - -const unsigned char YSF_SYNC_OK = 0x01U; - -const unsigned int YSF_CALLSIGN_LENGTH = 10U; - -const unsigned char YSF_FI_HEADER = 0x00U; -const unsigned char YSF_FI_COMMUNICATIONS = 0x01U; -const unsigned char YSF_FI_TERMINATOR = 0x02U; -const unsigned char YSF_FI_TEST = 0x03U; - -const unsigned char YSF_DT_VD_MODE1 = 0x00U; -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_INDIVIDUAL = 0x03U; - -const unsigned char YSF_MR_NOT_BUSY = 0x01U; -const unsigned char YSF_MR_BUSY = 0x02U; - -#endif diff --git a/YSFReflector/YSFReflector.cpp b/YSFReflector/YSFReflector.cpp deleted file mode 100644 index 7f71aca..0000000 --- a/YSFReflector/YSFReflector.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/* -* Copyright (C) 2016,2018,2020,2021 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. -*/ - -#include "YSFReflector.h" -#include "BlockList.h" -#include "StopWatch.h" -#include "Network.h" -#include "Version.h" -#include "Thread.h" -#include "Log.h" -#include "GitVersion.h" - -#if defined(_WIN32) || defined(_WIN64) -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#if defined(_WIN32) || defined(_WIN64) -const char* DEFAULT_INI_FILE = "YSFReflector.ini"; -#else -const char* DEFAULT_INI_FILE = "/etc/YSFReflector.ini"; -#endif - -#include -#include -#include -#include -#include -#include - -int main(int argc, char** argv) -{ - const char* iniFile = DEFAULT_INI_FILE; - if (argc > 1) { - for (int currentArg = 1; currentArg < argc; ++currentArg) { - std::string arg = argv[currentArg]; - if ((arg == "-v") || (arg == "--version")) { - ::fprintf(stdout, "YSFReflector version %s git #%.7s\n", VERSION, gitversion); - return 0; - } else if (arg.substr(0, 1) == "-") { - ::fprintf(stderr, "Usage: YSFReflector [-v|--version] [filename]\n"); - return 1; - } else { - iniFile = argv[currentArg]; - } - } - } - - CYSFReflector* reflector = new CYSFReflector(std::string(iniFile)); - reflector->run(); - delete reflector; - - return 0; -} - -CYSFReflector::CYSFReflector(const std::string& file) : -m_conf(file), -m_repeaters() -{ - CUDPSocket::startup(); -} - -CYSFReflector::~CYSFReflector() -{ - CUDPSocket::shutdown(); -} - -void CYSFReflector::run() -{ - bool ret = m_conf.read(); - if (!ret) { - ::fprintf(stderr, "YSFReflector: cannot read the .ini file\n"); - return; - } - -#if !defined(_WIN32) && !defined(_WIN64) - bool m_daemon = m_conf.getDaemon(); - if (m_daemon) { - // Create new process - pid_t pid = ::fork(); - if (pid == -1) { - ::fprintf(stderr, "Couldn't fork() , exiting\n"); - return; - } else if (pid != 0) { - exit(EXIT_SUCCESS); - } - - // Create new session and process group - if (::setsid() == -1) { - ::fprintf(stderr, "Couldn't setsid(), exiting\n"); - return; - } - - // Set the working directory to the root directory - if (::chdir("/") == -1) { - ::fprintf(stderr, "Couldn't cd /, exiting\n"); - return; - } - - // If we are currently root... - if (getuid() == 0) { - struct passwd* user = ::getpwnam("mmdvm"); - if (user == NULL) { - ::fprintf(stderr, "Could not get the mmdvm user, exiting\n"); - return; - } - - uid_t mmdvm_uid = user->pw_uid; - gid_t mmdvm_gid = user->pw_gid; - - // Set user and group ID's to mmdvm:mmdvm - if (setgid(mmdvm_gid) != 0) { - ::fprintf(stderr, "Could not set mmdvm GID, exiting\n"); - return; - } - - if (setuid(mmdvm_uid) != 0) { - ::fprintf(stderr, "Could not set mmdvm UID, exiting\n"); - return; - } - - // Double check it worked (AKA Paranoia) - if (setuid(0) != -1) { - ::fprintf(stderr, "It's possible to regain root - something is wrong!, exiting\n"); - return; - } - } - } -#endif - -#if !defined(_WIN32) && !defined(_WIN64) - ret = ::LogInitialise(m_daemon, m_conf.getLogFilePath(), m_conf.getLogFileRoot(), m_conf.getLogFileLevel(), m_conf.getLogDisplayLevel(), m_conf.getLogFileRotate()); -#else - ret = ::LogInitialise(false, m_conf.getLogFilePath(), m_conf.getLogFileRoot(), m_conf.getLogFileLevel(), m_conf.getLogDisplayLevel(), m_conf.getLogFileRotate()); -#endif - if (!ret) { - ::fprintf(stderr, "YSFReflector: unable to open the log file\n"); - return; - } - -#if !defined(_WIN32) && !defined(_WIN64) - if (m_daemon) { - ::close(STDIN_FILENO); - ::close(STDOUT_FILENO); - ::close(STDERR_FILENO); - } -#endif - - CNetwork network(m_conf.getNetworkPort(), m_conf.getId(), m_conf.getName(), m_conf.getDescription(), m_conf.getNetworkDebug()); - - ret = network.open(); - if (!ret) { - ::LogFinalise(); - return; - } - - CBlockList blockList(m_conf.getBlockListFile(), m_conf.getBlockListTime()); - blockList.start(); - - network.setCount(0); - - CStopWatch stopWatch; - stopWatch.start(); - - CTimer dumpTimer(1000U, 120U); - dumpTimer.start(); - - CTimer pollTimer(1000U, 5U); - pollTimer.start(); - - LogMessage("YSFReflector-%s is starting", VERSION); - LogMessage("Built %s %s (GitID #%.7s)", __TIME__, __DATE__, gitversion); - - CTimer watchdogTimer(1000U, 0U, 1500U); - - unsigned char tag[YSF_CALLSIGN_LENGTH]; - unsigned char src[YSF_CALLSIGN_LENGTH]; - unsigned char dst[YSF_CALLSIGN_LENGTH]; - - bool blocked = false; - - for (;;) { - unsigned char buffer[200U]; - sockaddr_storage addr; - unsigned int addrLen; - - unsigned int len = network.readData(buffer, 200U, addr, addrLen); - if (len > 0U) { - CYSFRepeater* rpt = findRepeater(addr); - if (::memcmp(buffer, "YSFP", 4U) == 0) { - if (rpt == NULL) { - rpt = new CYSFRepeater; - rpt->m_callsign = std::string((char*)(buffer + 4U), 10U); - ::memcpy(&rpt->m_addr, &addr, sizeof(struct sockaddr_storage)); - rpt->m_addrLen = addrLen; - m_repeaters.push_back(rpt); - network.setCount(m_repeaters.size()); - - char buff[80U]; - LogMessage("Adding %s (%s)", rpt->m_callsign.c_str(), CUDPSocket::display(addr, buff, 80U)); - } - rpt->m_timer.start(); - network.writePoll(addr, addrLen); - } else if (::memcmp(buffer + 0U, "YSFU", 4U) == 0 && rpt != NULL) { - char buff[80U]; - LogMessage("Removing %s (%s) unlinked", rpt->m_callsign.c_str(), CUDPSocket::display(addr, buff, 80U)); - - for (std::vector::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { - if (CUDPSocket::match((*it)->m_addr, rpt->m_addr)) { - delete *it; - m_repeaters.erase(it); - break; - } - } - network.setCount(m_repeaters.size()); - } else if (::memcmp(buffer + 0U, "YSFD", 4U) == 0 && rpt != NULL) { - if (!watchdogTimer.isRunning()) { - ::memcpy(tag, buffer + 4U, YSF_CALLSIGN_LENGTH); - - if (::memcmp(buffer + 14U, " ", YSF_CALLSIGN_LENGTH) != 0) - ::memcpy(src, buffer + 14U, YSF_CALLSIGN_LENGTH); - else - ::memcpy(src, "??????????", YSF_CALLSIGN_LENGTH); - - if (::memcmp(buffer + 24U, " ", YSF_CALLSIGN_LENGTH) != 0) - ::memcpy(dst, buffer + 24U, YSF_CALLSIGN_LENGTH); - else - ::memcpy(dst, "??????????", YSF_CALLSIGN_LENGTH); - - blocked = blockList.check(src); - if (blocked) - LogMessage("Data from %10.10s at %10.10s blocked", src, tag); - else - LogMessage("Received data from %10.10s to %10.10s at %10.10s", src, dst, tag); - } else { - if (::memcmp(tag, buffer + 4U, YSF_CALLSIGN_LENGTH) == 0) { - bool changed = false; - - if (::memcmp(buffer + 14U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(src, "??????????", YSF_CALLSIGN_LENGTH) == 0) { - ::memcpy(src, buffer + 14U, YSF_CALLSIGN_LENGTH); - changed = true; - } - - if (::memcmp(buffer + 24U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(dst, "??????????", YSF_CALLSIGN_LENGTH) == 0) { - ::memcpy(dst, buffer + 24U, YSF_CALLSIGN_LENGTH); - changed = true; - } - - if (changed) { - blocked = blockList.check(src); - if (blocked) - LogMessage("Data from %10.10s at %10.10s blocked", src, tag); - else - LogMessage("Received data from %10.10s to %10.10s at %10.10s", src, dst, tag); - } - } - } - - if (!blocked) { - watchdogTimer.start(); - - for (std::vector::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { - if (!CUDPSocket::match((*it)->m_addr, addr)) - network.writeData(buffer, (*it)->m_addr, (*it)->m_addrLen); - } - - if ((buffer[34U] & 0x01U) == 0x01U) { - LogMessage("Received end of transmission"); - watchdogTimer.stop(); - } - } - } - } - - unsigned int ms = stopWatch.elapsed(); - stopWatch.start(); - - pollTimer.clock(ms); - if (pollTimer.hasExpired()) { - for (std::vector::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) - network.writePoll((*it)->m_addr, (*it)->m_addrLen); - pollTimer.start(); - } - - // Remove any repeaters that haven't reported for a while - for (std::vector::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) - (*it)->m_timer.clock(ms); - - for (std::vector::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { - if ((*it)->m_timer.hasExpired()) { - char buff[80U]; - LogMessage("Removing %s (%s) disappeared", (*it)->m_callsign.c_str(), - CUDPSocket::display((*it)->m_addr, buff, 80U)); - - delete *it; - m_repeaters.erase(it); - network.setCount(m_repeaters.size()); - break; - } - } - - watchdogTimer.clock(ms); - if (watchdogTimer.isRunning() && watchdogTimer.hasExpired()) { - LogMessage("Network watchdog has expired"); - watchdogTimer.stop(); - } - - dumpTimer.clock(ms); - if (dumpTimer.hasExpired()) { - dumpRepeaters(); - dumpTimer.start(); - } - - blockList.clock(ms); - - if (ms < 5U) - CThread::sleep(5U); - } - - network.close(); - - ::LogFinalise(); -} - -CYSFRepeater* CYSFReflector::findRepeater(const sockaddr_storage& addr) const -{ - for (std::vector::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { - if (CUDPSocket::match(addr, (*it)->m_addr)) - return *it; - } - - return NULL; -} - -void CYSFReflector::dumpRepeaters() const -{ - if (m_repeaters.size() == 0U) { - LogMessage("No repeaters/gateways linked"); - return; - } - - LogMessage("Currently linked repeaters/gateways:"); - - for (std::vector::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { - char buffer[80U]; - LogMessage(" %s: %s %u/%u", (*it)->m_callsign.c_str(), - CUDPSocket::display((*it)->m_addr, buffer, 80U), - (*it)->m_timer.getTimer(), - (*it)->m_timer.getTimeout()); - } -} diff --git a/YSFReflector/YSFReflector.h b/YSFReflector/YSFReflector.h deleted file mode 100644 index 0da41a0..0000000 --- a/YSFReflector/YSFReflector.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -* Copyright (C) 2016,2020 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. -*/ - -#if !defined(YSFReflector_H) -#define YSFReflector_H - -#include "Timer.h" -#include "Conf.h" - -#include -#include -#include - -#if !defined(_WIN32) && !defined(_WIN64) -#include -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -class CYSFRepeater { -public: - CYSFRepeater() : - m_callsign(), - m_addr(), - m_addrLen(0U), - m_timer(1000U, 60U) - { - } - - std::string m_callsign; - sockaddr_storage m_addr; - unsigned int m_addrLen; - CTimer m_timer; -}; - -class CYSFReflector -{ -public: - CYSFReflector(const std::string& file); - ~CYSFReflector(); - - void run(); - -private: - CConf m_conf; - std::vector m_repeaters; - - CYSFRepeater* findRepeater(const sockaddr_storage& addr) const; - void dumpRepeaters() const; -}; - -#endif diff --git a/YSFReflector/YSFReflector.ini b/YSFReflector/YSFReflector.ini deleted file mode 100644 index f2cd2cc..0000000 --- a/YSFReflector/YSFReflector.ini +++ /dev/null @@ -1,25 +0,0 @@ -[General] -Daemon=1 - -[Info] -# Remember to register your YSFReflector at: -# https://register.ysfreflector.de -# Id=5 digits only -Name=16 characters max -Description=14 characters max - -[Log] -# Logging levels, 0=No logging -DisplayLevel=1 -FileLevel=1 -FilePath=. -FileRoot=YSFReflector -FileRotate=1 - -[Network] -Port=42000 -Debug=0 - -[Block List] -File=BlockList.txt -Time=5 diff --git a/YSFReflector/YSFReflector.sh b/YSFReflector/YSFReflector.sh deleted file mode 100644 index a5569da..0000000 --- a/YSFReflector/YSFReflector.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash -### BEGIN INIT INFO -# -# Provides: YSFReflector -# Required-Start: $all -# Required-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Example startscript YSFReflector - -# -### END INIT INFO -## Fill in name of program here. -PROG="YSFReflector" -PROG_PATH="/usr/local/bin/" -PROG_ARGS="/etc/YSFReflector.ini" -PIDFILE="/var/run/YSFReflector.pid" -USER="root" - -start() { - if [ -e $PIDFILE ]; then - ## Program is running, exit with error. - echo "Error! $PROG is currently running!" 1>&2 - exit 1 - else - cd $PROG_PATH - ./$PROG $PROG_ARGS - echo "$PROG started" - touch $PIDFILE - fi -} - -stop() { - if [ -e $PIDFILE ]; then - ## Program is running, so stop it - echo "$PROG is running" - rm -f $PIDFILE - killall $PROG - echo "$PROG stopped" - else - ## Program is not running, exit with error. - echo "Error! $PROG not started!" 1>&2 - exit 1 - fi -} - -## Check to see if we are running as root first. -## Found at -## http://www.cyberciti.biz/tips/shell-root-user-check-script.html -if [ "$(id -u)" != "0" ]; then - echo "This script must be run as root" 1>&2 - exit 1 -fi - -case "$1" in - start) - start - exit 0 - ;; - stop) - stop - exit 0 - ;; - reload|restart|force-reload) - stop - sleep 5 - start - exit 0 - ;; - **) - echo "Usage: $0 {start|stop|reload}" 1>&2 - exit 1 - ;; -esac -exit 0 -### END diff --git a/YSFReflector/YSFReflector.vcxproj b/YSFReflector/YSFReflector.vcxproj deleted file mode 100644 index cd80b58..0000000 --- a/YSFReflector/YSFReflector.vcxproj +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {317D87F1-3485-4739-9F94-A07738B8E19D} - Win32Proj - YSFReflector - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;HAVE_LOG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - ws2_32.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;HAVE_LOG_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - ws2_32.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;HAVE_LOG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - true - ws2_32.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;HAVE_LOG_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - true - ws2_32.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/YSFReflector/YSFReflector.vcxproj.filters b/YSFReflector/YSFReflector.vcxproj.filters deleted file mode 100644 index e31c4ed..0000000 --- a/YSFReflector/YSFReflector.vcxproj.filters +++ /dev/null @@ -1,83 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/YSFReflector/docker/Dockerfile b/YSFReflector/docker/Dockerfile deleted file mode 100644 index 1555452..0000000 --- a/YSFReflector/docker/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM debian:buster-slim AS builder - -RUN apt-get update && \ - apt-get install -y build-essential git - -RUN mkdir /code && \ - git clone https://github.com/g4klx/YSFClients.git /code && \ - cd /code/YSFReflector/ && \ - make clean all - -FROM debian:buster-slim - -ENV REFLECTOR_NAME set_me -ENV REFLECTOR_DESCRIPTION set_me - -RUN apt-get update && \ - apt-get install -y procps && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ - mkdir /app - -COPY --from=builder /code/YSFReflector/YSFReflector.ini /app/YSFReflector.ini -COPY --from=builder /code/YSFReflector/YSFReflector /app/YSFReflector -COPY entrypoint.sh /entrypoint.sh - -EXPOSE 42000/udp - -ENTRYPOINT ["/entrypoint.sh"] -CMD ["/app/YSFReflector", "/app/YSFReflector.ini"] -HEALTHCHECK CMD ps aux | grep [Y]SFReflector || exit 1 diff --git a/YSFReflector/docker/README.md b/YSFReflector/docker/README.md deleted file mode 100644 index 7767544..0000000 --- a/YSFReflector/docker/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# YSFReflector Docker Image - -The `Dockerfile` here is intended to produce an image which will be stored on [Docker Hub](https://hub.docker.com/). - -# Requirements - -* [Docker](https://docs.docker.com/install/) -* Firewall setup to accept 42000 (UDP) - -# Usage - -`docker run -e REFLECTOR_NAME=YOUR_NAME_HERE -eREFLECTOR_DESCRIPTION=YOUR_DESCRIPTION_HERE -p 42000:42000/udp neilbartley/ysfreflector:latest` - -# How to build - -Building isn't required unless you need a newer image or have made changes. - -``` -cd YSFReflector/docker -YSF_TAG=$(date +'%Y%m%d')-$(git rev-parse --short HEAD) -docker build --rm -t neilbartley/ysfreflector:$YSF_TAG . -docker tag neilbartley/ysfreflector:$YSF_TAG neilbartley/ysfreflector:latest -docker push neilbartley/ysfreflector:$YSF_TAG -docker push neilbartley/ysfreflector:latest -``` diff --git a/YSFReflector/docker/entrypoint.sh b/YSFReflector/docker/entrypoint.sh deleted file mode 100755 index 3a68231..0000000 --- a/YSFReflector/docker/entrypoint.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Disable daemon mode -sed -i -e "s/Daemon=1/Daemon=0/g" /app/YSFReflector.ini - -# Reflector name and description validation -if [ "${REFLECTOR_NAME}" == "set_me" ] ; then echo "Please set REFLECTOR_NAME environment variable with -e (max 16 characters)"; exit 1 ; fi -if [ ${#REFLECTOR_NAME} -gt 16 ] ; then echo "REFLECTOR_NAME environment variable can be at most 16 characters"; exit 1 ; fi -if [ "${REFLECTOR_DESCRIPTION}" == "set_me" ] ; then echo "Please set REFLECTOR_DESCRIPTION environment variable with -e (min 14 characters)"; exit 1 ; fi -if [ ${#REFLECTOR_DESCRIPTION} -gt 14 ] ; then echo "REFLECTOR_DESCRIPTION environment variable can be at most 14 characters"; exit 1 ; fi - -# Reflector name and description replacement in config file -sed -i -e "s/Name=.*/Name=${REFLECTOR_NAME}/g" /app/YSFReflector.ini -sed -i -e "s/Description=.*/Description=${REFLECTOR_DESCRIPTION}/g" /app/YSFReflector.ini - -echo "Remember to register your YSFReflector at: https://register.ysfreflector.de" - -exec "$@"