mirror of
https://github.com/oe7drt/YSFClients.git
synced 2025-12-06 05:32:02 +01:00
Compare commits
48 commits
f7f94b3ca1
...
b189b73eea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b189b73eea | ||
|
|
127cffd180 | ||
|
|
598854b2e3 | ||
|
|
ac0ba050c7 | ||
|
|
9df9a1aa16 | ||
|
|
450fd77a09 | ||
|
|
5eba410632 | ||
|
|
f4b985d165 | ||
|
|
8f88801628 | ||
|
|
76fd6f4921 | ||
|
|
00873b6cea | ||
|
|
c260e55680 | ||
|
|
75c8450870 | ||
|
|
d583357cab | ||
|
|
702d9e1312 | ||
|
|
d2044019a4 | ||
|
|
41edfe53c7 | ||
|
|
c3580fdcd3 | ||
|
|
af1cfbb251 | ||
|
|
f5a9843502 | ||
|
|
5015034749 | ||
|
|
30596b3cc4 | ||
|
|
811caaa823 | ||
|
|
b7260b4bf8 | ||
|
|
e61d856c6b | ||
|
|
daa1b56f3a | ||
|
|
e57b43377c | ||
|
|
b536f95e7e | ||
|
|
5ade21aaa2 | ||
|
|
80a91b9dd8 | ||
|
|
462eb2d571 | ||
|
|
ebb50c3acc | ||
|
|
f9431cbc0d | ||
|
|
8011768b96 | ||
|
|
6127174cfc | ||
|
|
ae29471f58 | ||
|
|
f811e65989 | ||
|
|
526f74c4ca | ||
|
|
5b6f6fb102 | ||
|
|
2af170c781 | ||
|
|
9ca8293609 | ||
|
|
46659c916a | ||
|
|
ca52eaf51e | ||
|
|
e67ddd1e87 | ||
|
|
aecc34ee64 | ||
|
|
dfe50c4245 | ||
|
|
91eccac90c | ||
|
|
bed3cbebd6 |
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2010-2014,2016,2017,2018,2020,2025 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
|
||||
|
|
@ -106,7 +106,7 @@ bool CAPRSWriter::open()
|
|||
return false;
|
||||
}
|
||||
|
||||
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL);
|
||||
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, nullptr);
|
||||
|
||||
LogMessage("Connected to GPSD");
|
||||
}
|
||||
|
|
@ -125,8 +125,8 @@ bool CAPRSWriter::open()
|
|||
|
||||
void CAPRSWriter::write(const unsigned char* source, const char* type, unsigned char radio, float fLatitude, float fLongitude)
|
||||
{
|
||||
assert(source != NULL);
|
||||
assert(type != NULL);
|
||||
assert(source != nullptr);
|
||||
assert(type != nullptr);
|
||||
|
||||
char callsign[15U];
|
||||
::memcpy(callsign, source, YSF_CALLSIGN_LENGTH);
|
||||
|
|
@ -219,7 +219,7 @@ void CAPRSWriter::close()
|
|||
|
||||
#if defined(USE_GPSD)
|
||||
if (m_gpsdEnabled) {
|
||||
::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL);
|
||||
::gps_stream(&m_gpsdData, WATCH_DISABLE, nullptr);
|
||||
::gps_close(&m_gpsdData);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -300,7 +300,7 @@ void CAPRSWriter::sendIdFrameMobile()
|
|||
return;
|
||||
|
||||
#if GPSD_API_MAJOR_VERSION >= 7
|
||||
if (::gps_read(&m_gpsdData, NULL, 0) <= 0)
|
||||
if (::gps_read(&m_gpsdData, nullptr, 0) <= 0)
|
||||
return;
|
||||
#else
|
||||
if (::gps_read(&m_gpsdData) <= 0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2025 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
|
||||
|
|
@ -63,7 +63,7 @@ const uint16_t CCITT16_TABLE2[] = {
|
|||
|
||||
void CCRC::addCCITT16(unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(in != nullptr);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
|
|
@ -84,7 +84,7 @@ void CCRC::addCCITT16(unsigned char *in, unsigned int length)
|
|||
|
||||
bool CCRC::checkCCITT16(const unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(in != nullptr);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
|
|
@ -104,7 +104,7 @@ bool CCRC::checkCCITT16(const unsigned char *in, unsigned int length)
|
|||
|
||||
unsigned char CCRC::addCRC(const unsigned char* in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(in != nullptr);
|
||||
|
||||
unsigned char crc = 0U;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2020,2025 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
|
||||
|
|
@ -27,17 +27,17 @@
|
|||
|
||||
const int BUFFER_SIZE = 500;
|
||||
|
||||
enum SECTION {
|
||||
SECTION_NONE,
|
||||
SECTION_GENERAL,
|
||||
SECTION_INFO,
|
||||
SECTION_LOG,
|
||||
SECTION_APRS,
|
||||
SECTION_YSF_NETWORK,
|
||||
SECTION_FCS_NETWORK,
|
||||
SECTION_IMRS_NETWORK,
|
||||
SECTION_DGID,
|
||||
SECTION_GPSD
|
||||
enum class SECTION {
|
||||
NONE,
|
||||
GENERAL,
|
||||
INFO,
|
||||
LOG,
|
||||
APRS,
|
||||
YSF_NETWORK,
|
||||
FCS_NETWORK,
|
||||
IMRS_NETWORK,
|
||||
DGID,
|
||||
GPSD
|
||||
};
|
||||
|
||||
CConf::CConf(const std::string& file) :
|
||||
|
|
@ -71,7 +71,7 @@ m_aprsAddress(),
|
|||
m_aprsPort(0U),
|
||||
m_aprsSuffix(),
|
||||
m_aprsDescription(),
|
||||
m_aprsSymbol(),
|
||||
m_aprsSymbol("/r"),
|
||||
m_ysfNetHosts(),
|
||||
m_ysfRFHangTime(60U),
|
||||
m_ysfNetHangTime(60U),
|
||||
|
|
@ -96,54 +96,54 @@ CConf::~CConf()
|
|||
bool CConf::read()
|
||||
{
|
||||
FILE* fp = ::fopen(m_file.c_str(), "rt");
|
||||
if (fp == NULL) {
|
||||
if (fp == nullptr) {
|
||||
::fprintf(stderr, "Couldn't open the .ini file - %s\n", m_file.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
SECTION section = SECTION_NONE;
|
||||
SECTION section = SECTION::NONE;
|
||||
|
||||
DGIdData* dgIdData = NULL;
|
||||
DGIdData* dgIdData = nullptr;
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) {
|
||||
while (::fgets(buffer, BUFFER_SIZE, fp) != nullptr) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
if (buffer[0U] == '[') {
|
||||
if (::strncmp(buffer, "[General]", 9U) == 0)
|
||||
section = SECTION_GENERAL;
|
||||
section = SECTION::GENERAL;
|
||||
else if (::strncmp(buffer, "[Info]", 6U) == 0)
|
||||
section = SECTION_INFO;
|
||||
section = SECTION::INFO;
|
||||
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
||||
section = SECTION_LOG;
|
||||
section = SECTION::LOG;
|
||||
else if (::strncmp(buffer, "[APRS]", 6U) == 0)
|
||||
section = SECTION_APRS;
|
||||
section = SECTION::APRS;
|
||||
else if (::strncmp(buffer, "[YSF Network]", 13U) == 0)
|
||||
section = SECTION_YSF_NETWORK;
|
||||
section = SECTION::YSF_NETWORK;
|
||||
else if (::strncmp(buffer, "[FCS Network]", 13U) == 0)
|
||||
section = SECTION_FCS_NETWORK;
|
||||
section = SECTION::FCS_NETWORK;
|
||||
else if (::strncmp(buffer, "[IMRS Network]", 14U) == 0)
|
||||
section = SECTION_IMRS_NETWORK;
|
||||
section = SECTION::IMRS_NETWORK;
|
||||
else if (::strncmp(buffer, "[DGId=", 6U) == 0) {
|
||||
section = SECTION_DGID;
|
||||
section = SECTION::DGID;
|
||||
dgIdData = new DGIdData;
|
||||
dgIdData->m_dgId = (unsigned int)::atoi(buffer + 6U);
|
||||
m_dgIdData.push_back(dgIdData);
|
||||
} else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
|
||||
section = SECTION_GPSD;
|
||||
section = SECTION::GPSD;
|
||||
else
|
||||
section = SECTION_NONE;
|
||||
section = SECTION::NONE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
char* key = ::strtok(buffer, " \t=\r\n");
|
||||
if (key == NULL)
|
||||
if (key == nullptr)
|
||||
continue;
|
||||
|
||||
char* value = ::strtok(NULL, "\r\n");
|
||||
if (value == NULL)
|
||||
char* value = ::strtok(nullptr, "\r\n");
|
||||
if (value == nullptr)
|
||||
continue;
|
||||
|
||||
// Remove quotes from the value
|
||||
|
|
@ -155,7 +155,7 @@ bool CConf::read()
|
|||
char *p;
|
||||
|
||||
// if value is not quoted, remove after # (to make comment)
|
||||
if ((p = strchr(value, '#')) != NULL)
|
||||
if ((p = strchr(value, '#')) != nullptr)
|
||||
*p = '\0';
|
||||
|
||||
// remove trailing tab/space
|
||||
|
|
@ -163,7 +163,7 @@ bool CConf::read()
|
|||
*p = '\0';
|
||||
}
|
||||
|
||||
if (section == SECTION_GENERAL) {
|
||||
if (section == SECTION::GENERAL) {
|
||||
if (::strcmp(key, "Callsign") == 0) {
|
||||
// Convert the callsign to upper case
|
||||
for (unsigned int i = 0U; value[i] != 0; i++)
|
||||
|
|
@ -194,7 +194,7 @@ bool CConf::read()
|
|||
m_debug = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Daemon") == 0)
|
||||
m_daemon = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_INFO) {
|
||||
} else if (section == SECTION::INFO) {
|
||||
if (::strcmp(key, "TXFrequency") == 0)
|
||||
m_txFrequency = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "RXFrequency") == 0)
|
||||
|
|
@ -209,7 +209,7 @@ bool CConf::read()
|
|||
m_height = ::atoi(value);
|
||||
else if (::strcmp(key, "Description") == 0)
|
||||
m_description = value;
|
||||
} else if (section == SECTION_LOG) {
|
||||
} else if (section == SECTION::LOG) {
|
||||
if (::strcmp(key, "FilePath") == 0)
|
||||
m_logFilePath = value;
|
||||
else if (::strcmp(key, "FileRoot") == 0)
|
||||
|
|
@ -220,7 +220,7 @@ bool CConf::read()
|
|||
m_logDisplayLevel = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "FileRotate") == 0)
|
||||
m_logFileRotate = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_APRS) {
|
||||
} else if (section == SECTION::APRS) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_aprsEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Address") == 0)
|
||||
|
|
@ -233,7 +233,7 @@ bool CConf::read()
|
|||
m_aprsDescription = value;
|
||||
else if (::strcmp(key, "Symbol") == 0)
|
||||
m_aprsSymbol = value;
|
||||
} else if (section == SECTION_YSF_NETWORK) {
|
||||
} else if (section == SECTION::YSF_NETWORK) {
|
||||
if (::strcmp(key, "Hosts") == 0)
|
||||
m_ysfNetHosts = value;
|
||||
else if (::strcmp(key, "RFHangTime") == 0)
|
||||
|
|
@ -242,22 +242,22 @@ bool CConf::read()
|
|||
m_ysfNetHangTime = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_ysfNetDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_FCS_NETWORK) {
|
||||
} else if (section == SECTION::FCS_NETWORK) {
|
||||
if (::strcmp(key, "RFHangTime") == 0)
|
||||
m_fcsRFHangTime = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "NetHangTime") == 0)
|
||||
m_fcsNetHangTime = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_fcsNetDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_IMRS_NETWORK) {
|
||||
} else if (section == SECTION::IMRS_NETWORK) {
|
||||
if (::strcmp(key, "RFHangTime") == 0)
|
||||
m_imrsRFHangTime = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "NetHangTime") == 0)
|
||||
m_imrsNetHangTime = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_imrsNetDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_DGID) {
|
||||
assert(dgIdData != NULL);
|
||||
} else if (section == SECTION::DGID) {
|
||||
assert(dgIdData != nullptr);
|
||||
if (::strcmp(key, "Type") == 0) {
|
||||
dgIdData->m_type = value;
|
||||
dgIdData->m_static = false;
|
||||
|
|
@ -296,14 +296,14 @@ bool CConf::read()
|
|||
dgIdData->m_netDGId = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Destination") == 0) {
|
||||
char* p1 = ::strtok(value, ",");
|
||||
char* p2 = ::strtok(NULL, "\r\n");
|
||||
char* p2 = ::strtok(nullptr, "\r\n");
|
||||
IMRSDestination* dest = new IMRSDestination;
|
||||
dest->m_dgId = (unsigned int)::atoi(p1);
|
||||
dest->m_address = p2;
|
||||
dgIdData->m_destinations.push_back(dest);
|
||||
} else if (::strcmp(key, "Debug") == 0)
|
||||
dgIdData->m_debug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_GPSD) {
|
||||
} else if (section == SECTION::GPSD) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_gpsdEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Address") == 0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016-2020,2024,2025 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
|
||||
|
|
@ -63,6 +63,17 @@ const unsigned char DT_VD_MODE2 = 0x02U;
|
|||
const unsigned char DT_VOICE_FR_MODE = 0x04U;
|
||||
const unsigned char DT_DATA_FR_MODE = 0x08U;
|
||||
|
||||
static bool m_killed = false;
|
||||
static int m_signal = 0;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
static void sigHandler(int signum)
|
||||
{
|
||||
m_killed = true;
|
||||
m_signal = signum;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* iniFile = DEFAULT_INI_FILE;
|
||||
|
|
@ -81,11 +92,40 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
CDGIdGateway* gateway = new CDGIdGateway(std::string(iniFile));
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
::signal(SIGINT, sigHandler);
|
||||
::signal(SIGTERM, sigHandler);
|
||||
::signal(SIGHUP, sigHandler);
|
||||
#endif
|
||||
|
||||
int ret = gateway->run();
|
||||
int ret = 0;
|
||||
|
||||
delete gateway;
|
||||
do {
|
||||
m_signal = 0;
|
||||
m_killed = false;
|
||||
|
||||
CDGIdGateway* gateway = new CDGIdGateway(std::string(iniFile));
|
||||
ret = gateway->run();
|
||||
|
||||
delete gateway;
|
||||
|
||||
switch (m_signal) {
|
||||
case 0:
|
||||
break;
|
||||
case 2:
|
||||
::LogInfo("DGIdGateway-%s exited on receipt of SIGINT", VERSION);
|
||||
break;
|
||||
case 15:
|
||||
::LogInfo("DGIdGateway-%s exited on receipt of SIGTERM", VERSION);
|
||||
break;
|
||||
case 1:
|
||||
::LogInfo("DGIdGateway-%s is restarting on receipt of SIGHUP", VERSION);
|
||||
break;
|
||||
default:
|
||||
::LogInfo("DGIdGateway-%s exited on receipt of an unknown signal", VERSION);
|
||||
break;
|
||||
}
|
||||
} while (m_signal == 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -94,8 +134,8 @@ CDGIdGateway::CDGIdGateway(const std::string& configFile) :
|
|||
m_callsign(),
|
||||
m_suffix(),
|
||||
m_conf(configFile),
|
||||
m_writer(NULL),
|
||||
m_gps(NULL)
|
||||
m_writer(nullptr),
|
||||
m_gps(nullptr)
|
||||
{
|
||||
CUDPSocket::startup();
|
||||
}
|
||||
|
|
@ -143,7 +183,7 @@ int CDGIdGateway::run()
|
|||
// If we are currently root...
|
||||
if (getuid() == 0) {
|
||||
struct passwd* user = ::getpwnam("mmdvm");
|
||||
if (user == NULL) {
|
||||
if (user == nullptr) {
|
||||
::fprintf(stderr, "Could not get the mmdvm user, exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -220,7 +260,7 @@ int CDGIdGateway::run()
|
|||
ret = imrs->open();
|
||||
if (!ret) {
|
||||
delete imrs;
|
||||
imrs = NULL;
|
||||
imrs = nullptr;
|
||||
}
|
||||
|
||||
unsigned int currentDGId = UNSET_DGID;
|
||||
|
|
@ -228,7 +268,7 @@ int CDGIdGateway::run()
|
|||
|
||||
CDGIdNetwork* dgIdNetwork[100U];
|
||||
for (unsigned int i = 0U; i < 100U; i++)
|
||||
dgIdNetwork[i] = NULL;
|
||||
dgIdNetwork[i] = nullptr;
|
||||
|
||||
std::vector<DGIdData*> dgIdData = m_conf.getDGIdData();
|
||||
for (std::vector<DGIdData*>::const_iterator it = dgIdData.begin(); it != dgIdData.end(); ++it) {
|
||||
|
|
@ -262,7 +302,7 @@ int CDGIdGateway::run()
|
|||
unsigned int local = (*it)->m_local;
|
||||
|
||||
CYSFReflector* reflector = reflectors->findByName(name);
|
||||
if (reflector != NULL) {
|
||||
if (reflector != nullptr) {
|
||||
dgIdNetwork[dgid] = new CYSFNetwork(local, reflector->m_name, reflector->m_addr, reflector->m_addrLen, m_callsign, statc, debug);
|
||||
dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2 | DT_VOICE_FR_MODE | DT_DATA_FR_MODE;
|
||||
dgIdNetwork[dgid]->m_static = statc;
|
||||
|
|
@ -274,7 +314,7 @@ int CDGIdGateway::run()
|
|||
LogWarning("Unknown YSF reflector: %s", name.c_str());
|
||||
}
|
||||
} else if (type == "IMRS") {
|
||||
if (imrs != NULL) {
|
||||
if (imrs != nullptr) {
|
||||
std::vector<IMRSDestination*> destinations = (*it)->m_destinations;
|
||||
std::vector<IMRSDest*> dests;
|
||||
std::string name = (*it)->m_name;
|
||||
|
|
@ -385,12 +425,12 @@ int CDGIdGateway::run()
|
|||
}
|
||||
}
|
||||
|
||||
if (dgIdNetwork[dgid] != NULL && dgIdNetwork[dgid] != imrs) {
|
||||
if (dgIdNetwork[dgid] != nullptr && dgIdNetwork[dgid] != imrs) {
|
||||
bool ret = dgIdNetwork[dgid]->open();
|
||||
if (!ret) {
|
||||
LogWarning("\tUnable to open connection");
|
||||
delete dgIdNetwork[dgid];
|
||||
dgIdNetwork[dgid] = NULL;
|
||||
dgIdNetwork[dgid] = nullptr;
|
||||
} else if (dgIdNetwork[dgid]->m_static) {
|
||||
LogMessage("\tLinking at startup");
|
||||
dgIdNetwork[dgid]->link();
|
||||
|
|
@ -411,10 +451,10 @@ int CDGIdGateway::run()
|
|||
LogMessage("DGIdGateway-%s is starting", VERSION);
|
||||
LogMessage("Built %s %s (GitID #%.7s)", __TIME__, __DATE__, gitversion);
|
||||
|
||||
DGID_STATUS state = DS_NOTLINKED;
|
||||
DGID_STATUS state = DGID_STATUS::NOTLINKED;
|
||||
unsigned int nPips = 0U;
|
||||
|
||||
for (;;) {
|
||||
while (!m_killed) {
|
||||
unsigned char buffer[200U];
|
||||
memset(buffer, 0U, 200U);
|
||||
|
||||
|
|
@ -428,29 +468,29 @@ int CDGIdGateway::run()
|
|||
dgId = 0U;
|
||||
|
||||
if (currentDGId == UNSET_DGID) {
|
||||
if (dgIdNetwork[dgId] != NULL && !dgIdNetwork[dgId]->m_static) {
|
||||
if (dgIdNetwork[dgId] != nullptr && !dgIdNetwork[dgId]->m_static) {
|
||||
dgIdNetwork[dgId]->link();
|
||||
dgIdNetwork[dgId]->link();
|
||||
dgIdNetwork[dgId]->link();
|
||||
}
|
||||
|
||||
if (dgIdNetwork[dgId] != NULL) {
|
||||
if (dgIdNetwork[dgId] != nullptr) {
|
||||
std::string desc = dgIdNetwork[dgId]->getDesc(dgId);
|
||||
LogMessage("DG-ID set to %u (%s) via RF", dgId, desc.c_str());
|
||||
currentDGId = dgId;
|
||||
state = DS_NOTLINKED;
|
||||
state = DGID_STATUS::NOTLINKED;
|
||||
} else {
|
||||
LogMessage("DG-ID set to %u (None) via RF", dgId);
|
||||
state = DS_NOTOPEN;
|
||||
state = DGID_STATUS::NOTOPEN;
|
||||
}
|
||||
|
||||
fromRF = true;
|
||||
}
|
||||
|
||||
if (m_gps != NULL)
|
||||
if (m_gps != nullptr)
|
||||
m_gps->data(buffer + 14U, buffer + 35U, fich);
|
||||
|
||||
if (currentDGId != UNSET_DGID && dgIdNetwork[currentDGId] != NULL) {
|
||||
if (currentDGId != UNSET_DGID && dgIdNetwork[currentDGId] != nullptr) {
|
||||
// Only allow the wanted modes through
|
||||
unsigned char dt = fich.getDT();
|
||||
if ((dt == YSF_DT_VD_MODE1 && (dgIdNetwork[currentDGId]->m_modes & DT_VD_MODE1) != 0U) ||
|
||||
|
|
@ -473,7 +513,7 @@ int CDGIdGateway::run()
|
|||
}
|
||||
|
||||
if ((buffer[34U] & 0x01U) == 0x01U) {
|
||||
if (m_gps != NULL)
|
||||
if (m_gps != nullptr)
|
||||
m_gps->reset();
|
||||
if (nPips > 0U && fromRF)
|
||||
bleepTimer.start();
|
||||
|
|
@ -481,7 +521,7 @@ int CDGIdGateway::run()
|
|||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
if (dgIdNetwork[i] != NULL) {
|
||||
if (dgIdNetwork[i] != nullptr) {
|
||||
unsigned int len = dgIdNetwork[i]->read(i, buffer);
|
||||
if (len > 0U && (i == currentDGId || currentDGId == UNSET_DGID)) {
|
||||
CYSFFICH fich;
|
||||
|
|
@ -502,7 +542,7 @@ int CDGIdGateway::run()
|
|||
std::string desc = dgIdNetwork[i]->getDesc(i);
|
||||
LogMessage("DG-ID set to %u (%s) via Network", i, desc.c_str());
|
||||
currentDGId = i;
|
||||
state = DS_LINKED;
|
||||
state = DGID_STATUS::LINKED;
|
||||
fromRF = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -516,16 +556,16 @@ int CDGIdGateway::run()
|
|||
rptNetwork.clock(ms);
|
||||
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
if (dgIdNetwork[i] != NULL)
|
||||
if (dgIdNetwork[i] != nullptr)
|
||||
dgIdNetwork[i]->clock(ms);
|
||||
}
|
||||
|
||||
if (m_writer != NULL)
|
||||
if (m_writer != nullptr)
|
||||
m_writer->clock(ms);
|
||||
|
||||
inactivityTimer.clock(ms);
|
||||
if (inactivityTimer.isRunning() && inactivityTimer.hasExpired()) {
|
||||
if (dgIdNetwork[currentDGId] != NULL && !dgIdNetwork[currentDGId]->m_static) {
|
||||
if (dgIdNetwork[currentDGId] != nullptr && !dgIdNetwork[currentDGId]->m_static) {
|
||||
dgIdNetwork[currentDGId]->unlink();
|
||||
dgIdNetwork[currentDGId]->unlink();
|
||||
dgIdNetwork[currentDGId]->unlink();
|
||||
|
|
@ -533,7 +573,7 @@ int CDGIdGateway::run()
|
|||
|
||||
LogMessage("DG-ID set to None via timeout");
|
||||
|
||||
state = DS_NOTLINKED;
|
||||
state = DGID_STATUS::NOTLINKED;
|
||||
currentDGId = UNSET_DGID;
|
||||
inactivityTimer.stop();
|
||||
|
||||
|
|
@ -550,20 +590,20 @@ int CDGIdGateway::run()
|
|||
nPips = 0U;
|
||||
}
|
||||
|
||||
if (currentDGId != UNSET_DGID && dgIdNetwork[currentDGId] != NULL) {
|
||||
if (currentDGId != UNSET_DGID && dgIdNetwork[currentDGId] != nullptr) {
|
||||
DGID_STATUS netState = dgIdNetwork[currentDGId]->getStatus();
|
||||
bool statc = dgIdNetwork[currentDGId]->m_static;
|
||||
if (fromRF && state != DS_LINKED && netState != DS_LINKED && statc)
|
||||
if (fromRF && state != DGID_STATUS::LINKED && netState != DGID_STATUS::LINKED && statc)
|
||||
nPips = 3U;
|
||||
else if (fromRF && state != DS_LINKED && netState == DS_LINKED)
|
||||
else if (fromRF && state != DGID_STATUS::LINKED && netState == DGID_STATUS::LINKED)
|
||||
nPips = 1U;
|
||||
else if (fromRF && state == DS_LINKED && netState != DS_LINKED)
|
||||
else if (fromRF && state == DGID_STATUS::LINKED && netState != DGID_STATUS::LINKED)
|
||||
nPips = 3U;
|
||||
state = netState;
|
||||
} else {
|
||||
if (fromRF && state != DS_NOTLINKED)
|
||||
if (fromRF && state != DGID_STATUS::NOTLINKED)
|
||||
nPips = 2U;
|
||||
state = DS_NOTLINKED;
|
||||
state = DGID_STATUS::NOTLINKED;
|
||||
}
|
||||
|
||||
if (ms < 5U)
|
||||
|
|
@ -573,14 +613,14 @@ int CDGIdGateway::run()
|
|||
rptNetwork.unlink();
|
||||
rptNetwork.close();
|
||||
|
||||
if (m_gps != NULL) {
|
||||
if (m_gps != nullptr) {
|
||||
m_writer->close();
|
||||
delete m_writer;
|
||||
delete m_gps;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
if (dgIdNetwork[i] != NULL && dgIdNetwork[i] != imrs) {
|
||||
if (dgIdNetwork[i] != nullptr && dgIdNetwork[i] != imrs) {
|
||||
dgIdNetwork[i]->unlink();
|
||||
dgIdNetwork[i]->unlink();
|
||||
dgIdNetwork[i]->unlink();
|
||||
|
|
@ -589,7 +629,7 @@ int CDGIdGateway::run()
|
|||
}
|
||||
}
|
||||
|
||||
if (imrs != NULL) {
|
||||
if (imrs != nullptr) {
|
||||
imrs->close();
|
||||
delete imrs;
|
||||
}
|
||||
|
|
@ -635,7 +675,7 @@ void CDGIdGateway::createGPS()
|
|||
bool ret = m_writer->open();
|
||||
if (!ret) {
|
||||
delete m_writer;
|
||||
m_writer = NULL;
|
||||
m_writer = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
|
@ -111,6 +114,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -124,6 +130,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -141,6 +150,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="APRSWriter.cpp" />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2020,2025 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
|
||||
|
|
@ -18,6 +18,13 @@
|
|||
|
||||
#include "DGIdNetwork.h"
|
||||
|
||||
CDGIdNetwork::CDGIdNetwork() :
|
||||
m_modes(0U),
|
||||
m_static(false),
|
||||
m_rfHangTime(0U),
|
||||
m_netHangTime(0U)
|
||||
{
|
||||
}
|
||||
|
||||
CDGIdNetwork::~CDGIdNetwork()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2020,2025 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
|
||||
|
|
@ -21,15 +21,16 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
enum DGID_STATUS {
|
||||
DS_NOTOPEN,
|
||||
DS_NOTLINKED,
|
||||
DS_LINKING,
|
||||
DS_LINKED
|
||||
enum class DGID_STATUS {
|
||||
NOTOPEN,
|
||||
NOTLINKED,
|
||||
LINKING,
|
||||
LINKED
|
||||
};
|
||||
|
||||
class CDGIdNetwork {
|
||||
public:
|
||||
CDGIdNetwork();
|
||||
virtual ~CDGIdNetwork() = 0;
|
||||
|
||||
virtual std::string getDesc(unsigned int dgId) = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020,2021,2025 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,8 +35,8 @@ m_debug(debug),
|
|||
m_addr(),
|
||||
m_addrLen(0U),
|
||||
m_static(statc),
|
||||
m_ping(NULL),
|
||||
m_info(NULL),
|
||||
m_ping(nullptr),
|
||||
m_info(nullptr),
|
||||
m_reflector(reflector),
|
||||
m_print(),
|
||||
m_buffer(1000U, "FCS Network Buffer"),
|
||||
|
|
@ -44,7 +44,7 @@ m_n(0U),
|
|||
m_sendPollTimer(1000U, 0U, 800U),
|
||||
m_recvPollTimer(1000U, 60U),
|
||||
m_resetTimer(1000U, 1U),
|
||||
m_state(DS_NOTOPEN)
|
||||
m_state(DGID_STATUS::NOTOPEN)
|
||||
{
|
||||
m_info = new unsigned char[100U];
|
||||
::sprintf((char*)m_info, "%9u%9u%-6.6s%-12.12s%7u", rxFrequency, txFrequency, locator.c_str(), FCS_VERSION, id);
|
||||
|
|
@ -85,7 +85,7 @@ bool CFCSNetwork::open()
|
|||
{
|
||||
if (m_addrLen == 0U) {
|
||||
LogError("Unable to resolve the address of %s", m_reflector.c_str());
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -93,10 +93,10 @@ bool CFCSNetwork::open()
|
|||
|
||||
bool ret = m_socket.open(m_addr);
|
||||
if (!ret) {
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
return false;
|
||||
} else {
|
||||
m_state = DS_NOTLINKED;
|
||||
m_state = DGID_STATUS::NOTLINKED;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -108,9 +108,9 @@ DGID_STATUS CFCSNetwork::getStatus()
|
|||
|
||||
void CFCSNetwork::write(unsigned int dgid, const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_state != DS_LINKED)
|
||||
if (m_state != DGID_STATUS::LINKED)
|
||||
return;
|
||||
|
||||
unsigned char buffer[130U];
|
||||
|
|
@ -127,10 +127,10 @@ void CFCSNetwork::write(unsigned int dgid, const unsigned char* data)
|
|||
|
||||
void CFCSNetwork::link()
|
||||
{
|
||||
if (m_state != DS_NOTLINKED)
|
||||
if (m_state != DGID_STATUS::NOTLINKED)
|
||||
return;
|
||||
|
||||
m_state = DS_LINKING;
|
||||
m_state = DGID_STATUS::LINKING;
|
||||
|
||||
m_sendPollTimer.start();
|
||||
m_recvPollTimer.start();
|
||||
|
|
@ -140,7 +140,7 @@ void CFCSNetwork::link()
|
|||
|
||||
void CFCSNetwork::unlink()
|
||||
{
|
||||
if (m_state != DS_LINKED)
|
||||
if (m_state != DGID_STATUS::LINKED)
|
||||
return;
|
||||
|
||||
m_socket.write((unsigned char*)"CLOSE ", 11U, m_addr, m_addrLen);
|
||||
|
|
@ -150,20 +150,20 @@ void CFCSNetwork::unlink()
|
|||
|
||||
LogMessage("Unlinked from %s", m_print.c_str());
|
||||
|
||||
m_state = DS_NOTLINKED;
|
||||
m_state = DGID_STATUS::NOTLINKED;
|
||||
}
|
||||
|
||||
void CFCSNetwork::clock(unsigned int ms)
|
||||
{
|
||||
if (m_state == DS_NOTOPEN)
|
||||
if (m_state == DGID_STATUS::NOTOPEN)
|
||||
return;
|
||||
|
||||
m_recvPollTimer.clock(ms);
|
||||
if (m_recvPollTimer.isRunning() && m_recvPollTimer.hasExpired()) {
|
||||
if (m_static) {
|
||||
m_state = DS_LINKING;
|
||||
m_state = DGID_STATUS::LINKING;
|
||||
} else {
|
||||
m_state = DS_NOTLINKED;
|
||||
m_state = DGID_STATUS::NOTLINKED;
|
||||
m_sendPollTimer.stop();
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +194,7 @@ void CFCSNetwork::clock(unsigned int ms)
|
|||
if (m_debug)
|
||||
CUtils::dump(1U, "FCS Network Data Received", buffer, length);
|
||||
|
||||
if (m_state == DS_NOTLINKED)
|
||||
if (m_state == DGID_STATUS::NOTLINKED)
|
||||
return;
|
||||
|
||||
if (!CUDPSocket::match(addr, m_addr))
|
||||
|
|
@ -206,10 +206,10 @@ void CFCSNetwork::clock(unsigned int ms)
|
|||
if (length == 7 || length == 10) {
|
||||
m_recvPollTimer.start();
|
||||
|
||||
if (m_state == DS_LINKING) {
|
||||
if (m_state == DGID_STATUS::LINKING) {
|
||||
LogMessage("Linked to %s", m_print.c_str());
|
||||
|
||||
m_state = DS_LINKED;
|
||||
m_state = DGID_STATUS::LINKED;
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "FCS Network Data Sent", m_info, 100U);
|
||||
|
|
@ -229,7 +229,7 @@ void CFCSNetwork::clock(unsigned int ms)
|
|||
|
||||
unsigned int CFCSNetwork::read(unsigned int dgid, unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_buffer.isEmpty())
|
||||
return 0U;
|
||||
|
|
@ -261,12 +261,12 @@ void CFCSNetwork::close()
|
|||
|
||||
LogMessage("Closing FCS network connection");
|
||||
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
}
|
||||
|
||||
void CFCSNetwork::writePoll()
|
||||
{
|
||||
if (m_state != DS_LINKING && m_state != DS_LINKED)
|
||||
if (m_state != DGID_STATUS::LINKING && m_state != DGID_STATUS::LINKED)
|
||||
return;
|
||||
|
||||
if (m_debug)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2018,2020,2024,2025 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
|
||||
|
|
@ -32,10 +32,10 @@ const unsigned char LONG_GPS[] = {0x47U, 0x64U};
|
|||
|
||||
CGPS::CGPS(CAPRSWriter* writer) :
|
||||
m_writer(writer),
|
||||
m_buffer(NULL),
|
||||
m_buffer(nullptr),
|
||||
m_sent(false)
|
||||
{
|
||||
assert(writer != NULL);
|
||||
assert(writer != nullptr);
|
||||
|
||||
m_buffer = new unsigned char[300U];
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ void CGPS::reset()
|
|||
|
||||
void CGPS::transmitGPS(const unsigned char* source)
|
||||
{
|
||||
assert(m_writer != NULL);
|
||||
assert(m_writer != nullptr);
|
||||
|
||||
// We don't know who its from!
|
||||
if (::memcmp(source, " ", YSF_CALLSIGN_LENGTH) == 0)
|
||||
|
|
@ -258,6 +258,9 @@ void CGPS::transmitGPS(const unsigned char* source)
|
|||
case 0x26U:
|
||||
::strcpy(radio, "DR-1X");
|
||||
break;
|
||||
case 0x27U:
|
||||
::strcpy(radio, "FT-991A");
|
||||
break;
|
||||
case 0x28U:
|
||||
::strcpy(radio, "FT-2D");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2010,2016,2025 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2002 by Robert H. Morelos-Zaragoza. All rights reserved.
|
||||
*/
|
||||
|
||||
|
|
@ -1096,7 +1096,7 @@ unsigned int CGolay24128::decode24128(unsigned int code)
|
|||
|
||||
unsigned int CGolay24128::decode24128(unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
assert(bytes != nullptr);
|
||||
|
||||
unsigned int code = bytes[0U];
|
||||
code <<= 8;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020,2025 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 @@
|
|||
CIMRSNetwork::CIMRSNetwork() :
|
||||
m_socket(IMRS_PORT),
|
||||
m_dgIds(),
|
||||
m_state(DS_NOTOPEN)
|
||||
m_state(DGID_STATUS::NOTOPEN)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ void CIMRSNetwork::addDGId(unsigned int dgId, const std::string& name, const std
|
|||
std::string CIMRSNetwork::getDesc(unsigned int dgId)
|
||||
{
|
||||
IMRSDGId* ptr = find(dgId);
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
return "IMRS: Unknown";
|
||||
|
||||
return "IMRS: " + ptr->m_name;
|
||||
|
|
@ -71,10 +71,10 @@ bool CIMRSNetwork::open()
|
|||
|
||||
bool ret = m_socket.open();
|
||||
if (!ret) {
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
return false;
|
||||
} else {
|
||||
m_state = DS_NOTLINKED;
|
||||
m_state = DGID_STATUS::NOTLINKED;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -86,10 +86,10 @@ DGID_STATUS CIMRSNetwork::getStatus()
|
|||
|
||||
void CIMRSNetwork::write(unsigned int dgId, const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
IMRSDGId* ptr = find(dgId);
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
return;
|
||||
|
||||
CUtils::dump(1U, "YSF Data Received", data, 155U);
|
||||
|
|
@ -112,8 +112,8 @@ void CIMRSNetwork::write(unsigned int dgId, const unsigned char* data)
|
|||
|
||||
bool CIMRSNetwork::writeHeaderTrailer(IMRSDGId* ptr, CYSFFICH& fich, const unsigned char* data)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
assert(data != NULL);
|
||||
assert(ptr != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
unsigned char buffer[200U];
|
||||
|
||||
|
|
@ -158,8 +158,8 @@ bool CIMRSNetwork::writeHeaderTrailer(IMRSDGId* ptr, CYSFFICH& fich, const unsig
|
|||
|
||||
bool CIMRSNetwork::writeData(IMRSDGId* ptr, CYSFFICH& fich, const unsigned char* data)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
assert(data != NULL);
|
||||
assert(ptr != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
unsigned char buffer[200U];
|
||||
unsigned int length = 0U;
|
||||
|
|
@ -253,8 +253,8 @@ bool CIMRSNetwork::writeData(IMRSDGId* ptr, CYSFFICH& fich, const unsigned char*
|
|||
|
||||
void CIMRSNetwork::readHeaderTrailer(IMRSDGId* ptr, CYSFFICH& fich, const unsigned char* data)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
assert(data != NULL);
|
||||
assert(ptr != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
unsigned char buffer[155U];
|
||||
|
||||
|
|
@ -298,8 +298,8 @@ void CIMRSNetwork::readHeaderTrailer(IMRSDGId* ptr, CYSFFICH& fich, const unsign
|
|||
|
||||
void CIMRSNetwork::readData(IMRSDGId* ptr, CYSFFICH& fich, const unsigned char* data)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
assert(data != NULL);
|
||||
assert(ptr != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
unsigned char buffer[155U];
|
||||
|
||||
|
|
@ -352,7 +352,7 @@ void CIMRSNetwork::readData(IMRSDGId* ptr, CYSFFICH& fich, const unsigned char*
|
|||
if (fn == 0U && ft == 1U) {
|
||||
// Copy the DCH
|
||||
payload.writeVoiceFRModeData(data + 7U, buffer + 35U);
|
||||
// NULL the unused section
|
||||
// nullptr the unused section
|
||||
::memset(buffer + 35U + YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES + 45U, 0x00U, 9U);
|
||||
// Copy the audio
|
||||
::memcpy(buffer + 35U + YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES + 54U, data + 27U + 0U, 18U);
|
||||
|
|
@ -403,7 +403,7 @@ void CIMRSNetwork::clock(unsigned int ms)
|
|||
CUtils::dump(1U, "IMRS Network Data Received", buffer, length);
|
||||
|
||||
IMRSDGId* ptr = find(addr);
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
return;
|
||||
|
||||
if (ptr->m_debug)
|
||||
|
|
@ -428,10 +428,10 @@ void CIMRSNetwork::clock(unsigned int ms)
|
|||
|
||||
unsigned int CIMRSNetwork::read(unsigned int dgId, unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
IMRSDGId* ptr = find(dgId);
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
return 0U;
|
||||
|
||||
if (ptr->m_buffer.isEmpty())
|
||||
|
|
@ -451,7 +451,7 @@ void CIMRSNetwork::close()
|
|||
|
||||
m_socket.close();
|
||||
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
}
|
||||
|
||||
IMRSDGId* CIMRSNetwork::find(const sockaddr_storage& addr) const
|
||||
|
|
@ -463,7 +463,7 @@ IMRSDGId* CIMRSNetwork::find(const sockaddr_storage& addr) const
|
|||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IMRSDGId* CIMRSNetwork::find(unsigned int dgId) const
|
||||
|
|
@ -473,5 +473,5 @@ IMRSDGId* CIMRSNetwork::find(unsigned int dgId) const
|
|||
return *it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020,2025 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
|
||||
|
|
@ -42,8 +42,8 @@ public:
|
|||
m_dgId(0U),
|
||||
m_name(),
|
||||
m_seqNo(0U),
|
||||
m_source(NULL),
|
||||
m_dest(NULL),
|
||||
m_source(nullptr),
|
||||
m_dest(nullptr),
|
||||
m_destinations(),
|
||||
m_debug(false),
|
||||
m_buffer(1000U, "IMRS Buffer")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2020,2025 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
|
||||
|
|
@ -37,7 +37,7 @@ static std::string m_filePath;
|
|||
static std::string m_fileRoot;
|
||||
static bool m_fileRotate = true;
|
||||
|
||||
static FILE* m_fpLog = NULL;
|
||||
static FILE* m_fpLog = nullptr;
|
||||
static bool m_daemon = false;
|
||||
|
||||
static unsigned int m_displayLevel = 2U;
|
||||
|
|
@ -59,10 +59,10 @@ static bool logOpenRotate()
|
|||
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)
|
||||
if (m_fpLog != nullptr)
|
||||
return true;
|
||||
} else {
|
||||
if (m_fpLog != NULL)
|
||||
if (m_fpLog != nullptr)
|
||||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ static bool logOpenRotate()
|
|||
::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) {
|
||||
if ((m_fpLog = ::fopen(filename, "a+t")) != nullptr) {
|
||||
status = true;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
|
|
@ -94,7 +94,7 @@ static bool logOpenNoRotate()
|
|||
if (m_fileLevel == 0U)
|
||||
return true;
|
||||
|
||||
if (m_fpLog != NULL)
|
||||
if (m_fpLog != nullptr)
|
||||
return true;
|
||||
|
||||
char filename[200U];
|
||||
|
|
@ -104,7 +104,7 @@ static bool logOpenNoRotate()
|
|||
::sprintf(filename, "%s/%s.log", m_filePath.c_str(), m_fileRoot.c_str());
|
||||
#endif
|
||||
|
||||
if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) {
|
||||
if ((m_fpLog = ::fopen(filename, "a+t")) != nullptr) {
|
||||
status = true;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
|
|
@ -141,13 +141,13 @@ bool LogInitialise(bool daemon, const std::string& filePath, const std::string&
|
|||
|
||||
void LogFinalise()
|
||||
{
|
||||
if (m_fpLog != NULL)
|
||||
if (m_fpLog != nullptr)
|
||||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
void Log(unsigned int level, const char* fmt, ...)
|
||||
{
|
||||
assert(fmt != NULL);
|
||||
assert(fmt != nullptr);
|
||||
|
||||
char buffer[501U];
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -157,7 +157,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
|||
::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);
|
||||
::gettimeofday(&now, nullptr);
|
||||
|
||||
struct tm* tm = ::gmtime(&now.tv_sec);
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
|||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
|
||||
::vsnprintf(buffer + ::strlen(buffer), 500, fmt, vl);
|
||||
::vsnprintf(buffer + ::strlen(buffer), 500 - ::strlen(buffer), fmt, vl);
|
||||
|
||||
va_end(vl);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2009,2012,2013,2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2006-2009,2012,2013,2015,2016,2025 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,12 +30,12 @@ public:
|
|||
CRingBuffer(unsigned int length, const char* name) :
|
||||
m_length(length),
|
||||
m_name(name),
|
||||
m_buffer(NULL),
|
||||
m_buffer(nullptr),
|
||||
m_iPtr(0U),
|
||||
m_oPtr(0U)
|
||||
{
|
||||
assert(length > 0U);
|
||||
assert(name != NULL);
|
||||
assert(name != nullptr);
|
||||
|
||||
m_buffer = new T[length];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2018,2025 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
|
||||
|
|
@ -77,7 +77,7 @@ CStopWatch::~CStopWatch()
|
|||
unsigned long long CStopWatch::time() const
|
||||
{
|
||||
struct timeval now;
|
||||
::gettimeofday(&now, NULL);
|
||||
::gettimeofday(&now, nullptr);
|
||||
|
||||
return now.tv_sec * 1000ULL + now.tv_usec / 1000ULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2025 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
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
void CSync::add(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
::memcpy(data, YSF_SYNC_BYTES, YSF_SYNC_LENGTH_BYTES);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2020,2025 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,9 +31,9 @@ CThread::~CThread()
|
|||
|
||||
bool CThread::run()
|
||||
{
|
||||
m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL);
|
||||
m_handle = ::CreateThread(nullptr, 0, &helper, this, 0, nullptr);
|
||||
|
||||
return m_handle != NULL;
|
||||
return m_handle != nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -74,13 +74,13 @@ CThread::~CThread()
|
|||
|
||||
bool CThread::run()
|
||||
{
|
||||
return ::pthread_create(&m_thread, NULL, helper, this) == 0;
|
||||
return ::pthread_create(&m_thread, nullptr, helper, this) == 0;
|
||||
}
|
||||
|
||||
|
||||
void CThread::wait()
|
||||
{
|
||||
::pthread_join(m_thread, NULL);
|
||||
::pthread_join(m_thread, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ void* CThread::helper(void* arg)
|
|||
|
||||
p->entry();
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CThread::sleep(unsigned int ms)
|
||||
|
|
@ -100,7 +100,7 @@ void CThread::sleep(unsigned int ms)
|
|||
ts.tv_sec = ms / 1000U;
|
||||
ts.tv_nsec = (ms % 1000U) * 1000000U;
|
||||
|
||||
::nanosleep(&ts, NULL);
|
||||
::nanosleep(&ts, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2006-2016,2020,2024,2025 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,29 +34,27 @@
|
|||
#endif
|
||||
|
||||
CUDPSocket::CUDPSocket(const std::string& address, unsigned short port) :
|
||||
m_address_save(address),
|
||||
m_port_save(port),
|
||||
m_counter(0U)
|
||||
m_localAddress(address),
|
||||
m_localPort(port),
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
m_fd(INVALID_SOCKET),
|
||||
#else
|
||||
m_fd(-1),
|
||||
#endif
|
||||
m_af(AF_UNSPEC)
|
||||
{
|
||||
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 short port) :
|
||||
m_address_save(),
|
||||
m_port_save(port),
|
||||
m_counter(0U)
|
||||
m_localAddress(),
|
||||
m_localPort(port),
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
m_fd(INVALID_SOCKET),
|
||||
#else
|
||||
m_fd(-1),
|
||||
#endif
|
||||
m_af(AF_UNSPEC)
|
||||
{
|
||||
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()
|
||||
|
|
@ -93,10 +91,10 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
|
|||
std::string portstr = std::to_string(port);
|
||||
struct addrinfo *res;
|
||||
|
||||
/* port is always digits, no needs to lookup service */
|
||||
/* 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);
|
||||
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));
|
||||
|
|
@ -107,9 +105,11 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
|
|||
return err;
|
||||
}
|
||||
|
||||
::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen);
|
||||
address_length = (unsigned int)res->ai_addrlen;
|
||||
|
||||
freeaddrinfo(res);
|
||||
::memcpy(&addr, res->ai_addr, address_length);
|
||||
|
||||
::freeaddrinfo(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -119,35 +119,35 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
|
|||
if (addr1.ss_family != addr2.ss_family)
|
||||
return false;
|
||||
|
||||
if (type == IMT_ADDRESS_AND_PORT) {
|
||||
if (type == IPMATCHTYPE::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;
|
||||
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) {
|
||||
} else if (type == IPMATCHTYPE::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;
|
||||
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;
|
||||
|
|
@ -156,42 +156,45 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
|
|||
|
||||
bool CUDPSocket::isNone(const sockaddr_storage& addr)
|
||||
{
|
||||
struct sockaddr_in *in = (struct sockaddr_in *)&addr;
|
||||
struct sockaddr_in *in = (struct sockaddr_in*)&addr;
|
||||
|
||||
return ((addr.ss_family == AF_INET) && (in->sin_addr.s_addr == htonl(INADDR_NONE)));
|
||||
}
|
||||
|
||||
bool CUDPSocket::open(const sockaddr_storage& address)
|
||||
{
|
||||
return open(address.ss_family);
|
||||
m_af = address.ss_family;
|
||||
|
||||
return open();
|
||||
}
|
||||
|
||||
bool CUDPSocket::open(unsigned int af)
|
||||
bool CUDPSocket::open()
|
||||
{
|
||||
return open(0, af, m_address_save, m_port_save);
|
||||
}
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
assert(m_fd == INVALID_SOCKET);
|
||||
#else
|
||||
assert(m_fd == -1);
|
||||
#endif
|
||||
|
||||
bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port)
|
||||
{
|
||||
sockaddr_storage addr;
|
||||
unsigned int addrlen;
|
||||
struct addrinfo hints;
|
||||
|
||||
::memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = af;
|
||||
hints.ai_family = m_af;
|
||||
|
||||
/* to determine protocol family, call lookup() first. */
|
||||
int err = lookup(address, port, addr, addrlen, hints);
|
||||
// To determine protocol family, call lookup() on the local address first.
|
||||
int err = lookup(m_localAddress, m_localPort, addr, addrlen, hints);
|
||||
if (err != 0) {
|
||||
LogError("The local address is invalid - %s", address.c_str());
|
||||
LogError("The local address is invalid - %s", m_localAddress.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
close(index);
|
||||
m_af = addr.ss_family;
|
||||
|
||||
int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
m_fd = ::socket(m_af, SOCK_DGRAM, 0);
|
||||
if (m_fd < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Cannot create the UDP socket, err: %lu", ::GetLastError());
|
||||
#else
|
||||
|
|
@ -200,62 +203,58 @@ bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std
|
|||
return false;
|
||||
}
|
||||
|
||||
m_address[index] = address;
|
||||
m_port[index] = port;
|
||||
m_af[index] = addr.ss_family;
|
||||
m_fd[index] = fd;
|
||||
|
||||
if (port > 0U) {
|
||||
if (m_localPort > 0U) {
|
||||
int reuse = 1;
|
||||
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
|
||||
if (::setsockopt(m_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
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) {
|
||||
if (::bind(m_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
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo("Opening UDP port on %hu", port);
|
||||
LogInfo("Opening UDP port on %hu", m_localPort);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length)
|
||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int& addressLength)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
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)
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (m_fd == INVALID_SOCKET)
|
||||
return 0;
|
||||
#else
|
||||
if (m_fd == -1)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
// Check that the readfrom() won't block
|
||||
struct pollfd pfd;
|
||||
pfd.fd = m_fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
|
||||
// Return immediately
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int ret = WSAPoll(pfd, n, 0);
|
||||
int ret = WSAPoll(&pfd, 1, 0);
|
||||
#else
|
||||
int ret = ::poll(pfd, n, 0);
|
||||
int ret = ::poll(&pfd, 1, 0);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -266,14 +265,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
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)
|
||||
if ((pfd.revents & POLLIN) == 0)
|
||||
return 0;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -283,9 +275,9 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr*)&address, &size);
|
||||
#else
|
||||
ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr*)&address, &size);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -294,7 +286,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
LogError("Error returned from recvfrom, err: %d", errno);
|
||||
|
||||
if (len == -1 && errno == ENOTSOCK) {
|
||||
LogMessage("Re-opening UDP port on %hu", m_port[index]);
|
||||
LogMessage("Re-opening UDP port on %hu", m_localPort);
|
||||
close();
|
||||
open();
|
||||
}
|
||||
|
|
@ -302,43 +294,43 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
return -1;
|
||||
}
|
||||
|
||||
m_counter++;
|
||||
address_length = size;
|
||||
addressLength = size;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length)
|
||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
assert(length > 0U);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
assert(m_fd != INVALID_SOCKET);
|
||||
#else
|
||||
assert(m_fd >= 0);
|
||||
#endif
|
||||
|
||||
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);
|
||||
int ret = ::sendto(m_fd, (char*)buffer, length, 0, (sockaddr*)&address, addressLength);
|
||||
#else
|
||||
ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
|
||||
ssize_t ret = ::sendto(m_fd, (char*)buffer, length, 0, (sockaddr*)&address, addressLength);
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Error returned from sendto, err: %lu", ::GetLastError());
|
||||
LogError("Error returned from sendto, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Error returned from sendto, err: %d", errno);
|
||||
LogError("Error returned from sendto, err: %d", errno);
|
||||
#endif
|
||||
} else {
|
||||
} else {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (ret == int(length))
|
||||
result = true;
|
||||
if (ret == int(length))
|
||||
result = true;
|
||||
#else
|
||||
if (ret == ssize_t(length))
|
||||
result = true;
|
||||
if (ret == ssize_t(length))
|
||||
result = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -346,18 +338,15 @@ bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const s
|
|||
|
||||
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;
|
||||
if (m_fd != INVALID_SOCKET) {
|
||||
::closesocket(m_fd);
|
||||
m_fd = INVALID_SOCKET;
|
||||
}
|
||||
#else
|
||||
if (m_fd >= 0) {
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2011,2013,2015,2016,2020,2024,2025 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,13 +35,9 @@
|
|||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#if !defined(UDP_SOCKET_MAX)
|
||||
#define UDP_SOCKET_MAX 1
|
||||
#endif
|
||||
|
||||
enum IPMATCHTYPE {
|
||||
IMT_ADDRESS_AND_PORT,
|
||||
IMT_ADDRESS_ONLY
|
||||
enum class IPMATCHTYPE {
|
||||
ADDRESS_AND_PORT,
|
||||
ADDRESS_ONLY
|
||||
};
|
||||
|
||||
class CUDPSocket {
|
||||
|
|
@ -50,34 +46,34 @@ public:
|
|||
CUDPSocket(unsigned short port = 0U);
|
||||
~CUDPSocket();
|
||||
|
||||
bool open(unsigned int af = AF_UNSPEC);
|
||||
bool open();
|
||||
bool open(const sockaddr_storage& address);
|
||||
bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short 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);
|
||||
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength);
|
||||
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength);
|
||||
|
||||
void close();
|
||||
void close(const unsigned int index);
|
||||
|
||||
static void startup();
|
||||
static void shutdown();
|
||||
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength, struct addrinfo& hints);
|
||||
|
||||
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
|
||||
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IPMATCHTYPE::ADDRESS_AND_PORT);
|
||||
|
||||
static bool isNone(const sockaddr_storage& addr);
|
||||
|
||||
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;
|
||||
std::string m_localAddress;
|
||||
unsigned short m_localPort;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SOCKET m_fd;
|
||||
int m_af;
|
||||
#else
|
||||
int m_fd;
|
||||
sa_family_t m_af;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009,2014,2015,2016 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2009,2014,2015,2016,2025 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
|
||||
|
|
@ -19,14 +19,14 @@
|
|||
|
||||
void CUtils::dump(const std::string& title, const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
dump(2U, title, data, length);
|
||||
}
|
||||
|
||||
void CUtils::dump(int level, const std::string& title, const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
::Log(level, "%s", title.c_str());
|
||||
|
||||
|
|
@ -72,14 +72,14 @@ void CUtils::dump(int level, const std::string& title, const unsigned char* data
|
|||
|
||||
void CUtils::dump(const std::string& title, const bool* bits, unsigned int length)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
dump(2U, title, bits, length);
|
||||
}
|
||||
|
||||
void CUtils::dump(int level, const std::string& title, const bool* bits, unsigned int length)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
unsigned char bytes[100U];
|
||||
unsigned int nBytes = 0U;
|
||||
|
|
@ -91,7 +91,7 @@ void CUtils::dump(int level, const std::string& title, const bool* bits, unsigne
|
|||
|
||||
void CUtils::byteToBitsBE(unsigned char byte, bool* bits)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
bits[0U] = (byte & 0x80U) == 0x80U;
|
||||
bits[1U] = (byte & 0x40U) == 0x40U;
|
||||
|
|
@ -105,7 +105,7 @@ void CUtils::byteToBitsBE(unsigned char byte, bool* bits)
|
|||
|
||||
void CUtils::byteToBitsLE(unsigned char byte, bool* bits)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
bits[0U] = (byte & 0x01U) == 0x01U;
|
||||
bits[1U] = (byte & 0x02U) == 0x02U;
|
||||
|
|
@ -119,7 +119,7 @@ void CUtils::byteToBitsLE(unsigned char byte, bool* bits)
|
|||
|
||||
void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
byte = bits[0U] ? 0x80U : 0x00U;
|
||||
byte |= bits[1U] ? 0x40U : 0x00U;
|
||||
|
|
@ -133,7 +133,7 @@ void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
|
|||
|
||||
void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
byte = bits[0U] ? 0x01U : 0x00U;
|
||||
byte |= bits[1U] ? 0x02U : 0x00U;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2021,2023,2024,2025 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
|
||||
|
|
@ -19,6 +19,6 @@
|
|||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
const char* VERSION = "20230212";
|
||||
const char* VERSION = "20250607";
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2016,2025 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
|
||||
|
|
@ -36,12 +36,12 @@ const uint32_t M = 2U;
|
|||
const unsigned int K = 5U;
|
||||
|
||||
CYSFConvolution::CYSFConvolution() :
|
||||
m_metrics1(NULL),
|
||||
m_metrics2(NULL),
|
||||
m_oldMetrics(NULL),
|
||||
m_newMetrics(NULL),
|
||||
m_decisions(NULL),
|
||||
m_dp(NULL)
|
||||
m_metrics1(nullptr),
|
||||
m_metrics2(nullptr),
|
||||
m_oldMetrics(nullptr),
|
||||
m_newMetrics(nullptr),
|
||||
m_decisions(nullptr),
|
||||
m_dp(nullptr)
|
||||
{
|
||||
m_metrics1 = new uint16_t[16U];
|
||||
m_metrics2 = new uint16_t[16U];
|
||||
|
|
@ -98,7 +98,7 @@ void CYSFConvolution::decode(uint8_t s0, uint8_t s1)
|
|||
|
||||
void CYSFConvolution::chainback(unsigned char* out, unsigned int nBits)
|
||||
{
|
||||
assert(out != NULL);
|
||||
assert(out != nullptr);
|
||||
|
||||
uint32_t state = 0U;
|
||||
|
||||
|
|
@ -115,8 +115,8 @@ void CYSFConvolution::chainback(unsigned char* out, unsigned int nBits)
|
|||
|
||||
void CYSFConvolution::encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(out != NULL);
|
||||
assert(in != nullptr);
|
||||
assert(out != nullptr);
|
||||
assert(nBits > 0U);
|
||||
|
||||
uint8_t d1 = 0U, d2 = 0U, d3 = 0U, d4 = 0U;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2019,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2019,2020,2025 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,7 +55,7 @@ const unsigned int INTERLEAVE_TABLE[] = {
|
|||
38U, 78U, 118U, 158U, 198U};
|
||||
|
||||
CYSFFICH::CYSFFICH(const CYSFFICH& fich) :
|
||||
m_fich(NULL)
|
||||
m_fich(nullptr)
|
||||
{
|
||||
m_fich = new unsigned char[6U];
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ m_fich(NULL)
|
|||
}
|
||||
|
||||
CYSFFICH::CYSFFICH() :
|
||||
m_fich(NULL)
|
||||
m_fich(nullptr)
|
||||
{
|
||||
m_fich = new unsigned char[6U];
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ CYSFFICH::~CYSFFICH()
|
|||
|
||||
bool CYSFFICH::decode(const unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
assert(bytes != nullptr);
|
||||
|
||||
// Skip the sync bytes
|
||||
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||
|
|
@ -116,7 +116,7 @@ bool CYSFFICH::decode(const unsigned char* bytes)
|
|||
|
||||
void CYSFFICH::encode(unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
assert(bytes != nullptr);
|
||||
|
||||
// Skip the sync bytes
|
||||
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
43
DGIdGateway/YSFHostsUpdate.sh
Normal file
43
DGIdGateway/YSFHostsUpdate.sh
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#! /bin/bash
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2025 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.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# Full path to the YSFHosts hosts file
|
||||
#
|
||||
YSFHOSTS=/path/to/YSFHosts.txt
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Do not edit below here
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Check we are root
|
||||
if [ "$(id -u)" != "0" ]
|
||||
then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download the YSFHosts.txt file
|
||||
curl https://dvref.com/downloads/YSFHosts-resolved.txt > ${YSFHOSTS}
|
||||
|
||||
exit 0
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# YSFHostsupdate.sh
|
||||
#
|
||||
# Copyright (C) 2016 by Tony Corbett G0WFV
|
||||
# Adapted to YSFHosts by Paul Nannery KC2VRJ on 6/28/2016 with all crdeit
|
||||
# to G0WFV for the orignal script.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# On a Linux based system, such as a Raspberry Pi, this script will perform all
|
||||
# the steps required to maintain the YSFHosts.txt (or similar) file for you.
|
||||
#
|
||||
# It is designed to run from crontab and will download the YSFHosts from the
|
||||
# master ysfreflector.de database and optionally keep a backup of previously
|
||||
# created files for you.
|
||||
#
|
||||
# It will also prune the number of backup files according to a value specified
|
||||
# by you in the configuration below.
|
||||
#
|
||||
# To install in root's crontab use the command ...
|
||||
#
|
||||
# sudo crontab -e
|
||||
#
|
||||
# ... and add the following line to the bottom of the file ...
|
||||
#
|
||||
# 0 0 * * * /path/to/script/YSFHostsupdate.sh 1>/dev/null 2>&1
|
||||
#
|
||||
# ... where /path/to/script/ should be replaced by the path to this script.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# CONFIGURATION
|
||||
#
|
||||
# Full path to YSFHosts
|
||||
YSFHOSTS=/path/to/YSFHosts.txt
|
||||
|
||||
# How many YSFHosts files do you want backed up (0 = do not keep backups)
|
||||
YSFHOSTSFILEBACKUP=1
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Do not edit below here
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Check we are root
|
||||
if [ "$(id -u)" != "0" ]
|
||||
then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create backup of old file
|
||||
if [ ${YSFHOSTSFILEBACKUP} -ne 0 ]
|
||||
then
|
||||
cp ${YSFHOSTS} ${YSFHOSTS}.$(date +%d%m%y)
|
||||
fi
|
||||
|
||||
# Prune backups
|
||||
BACKUPCOUNT=$(ls ${YSFHOSTS}.* | wc -l)
|
||||
BACKUPSTODELETE=$(expr ${BACKUPCOUNT} - ${YSFHOSTSFILEBACKUP})
|
||||
|
||||
if [ ${BACKUPCOUNT} -gt ${YSFHOSTSFILEBACKUP} ]
|
||||
then
|
||||
for f in $(ls -tr ${YSFHOSTS}.* | head -${BACKUPSTODELETE})
|
||||
do
|
||||
rm -f $f
|
||||
done
|
||||
fi
|
||||
|
||||
# Generate YSFHosts.txt file
|
||||
curl https://register.ysfreflector.de/export_csv.php > ${YSFHOSTS}
|
||||
|
||||
exit 0
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020,2025 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
|
||||
|
|
@ -33,13 +33,13 @@ m_debug(debug),
|
|||
m_addr(addr),
|
||||
m_addrLen(addrLen),
|
||||
m_static(true),
|
||||
m_poll(NULL),
|
||||
m_unlink(NULL),
|
||||
m_poll(nullptr),
|
||||
m_unlink(nullptr),
|
||||
m_buffer(1000U, "YSF Network Buffer"),
|
||||
m_sendPollTimer(1000U, 5U),
|
||||
m_recvPollTimer(1000U, 60U),
|
||||
m_name(name),
|
||||
m_state(DS_NOTOPEN)
|
||||
m_state(DGID_STATUS::NOTOPEN)
|
||||
{
|
||||
m_poll = new unsigned char[14U];
|
||||
::memcpy(m_poll + 0U, "YSFP", 4U);
|
||||
|
|
@ -62,13 +62,13 @@ m_debug(debug),
|
|||
m_addr(addr),
|
||||
m_addrLen(addrLen),
|
||||
m_static(statc),
|
||||
m_poll(NULL),
|
||||
m_unlink(NULL),
|
||||
m_poll(nullptr),
|
||||
m_unlink(nullptr),
|
||||
m_buffer(1000U, "YSF Network Buffer"),
|
||||
m_sendPollTimer(1000U, 5U),
|
||||
m_recvPollTimer(1000U, 60U),
|
||||
m_name(name),
|
||||
m_state(DS_NOTOPEN)
|
||||
m_state(DGID_STATUS::NOTOPEN)
|
||||
{
|
||||
m_poll = new unsigned char[14U];
|
||||
::memcpy(m_poll + 0U, "YSFP", 4U);
|
||||
|
|
@ -105,7 +105,7 @@ bool CYSFNetwork::open()
|
|||
{
|
||||
if (m_addrLen == 0U) {
|
||||
LogError("Unable to resolve the address of the YSF network");
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -113,10 +113,10 @@ bool CYSFNetwork::open()
|
|||
|
||||
bool ret = m_socket.open(m_addr);
|
||||
if (!ret) {
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
return false;
|
||||
} else {
|
||||
m_state = DS_NOTLINKED;
|
||||
m_state = DGID_STATUS::NOTLINKED;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -128,9 +128,9 @@ DGID_STATUS CYSFNetwork::getStatus()
|
|||
|
||||
void CYSFNetwork::write(unsigned int dgid, const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_state != DS_LINKED)
|
||||
if (m_state != DGID_STATUS::LINKED)
|
||||
return;
|
||||
|
||||
if (m_debug)
|
||||
|
|
@ -141,10 +141,10 @@ void CYSFNetwork::write(unsigned int dgid, const unsigned char* data)
|
|||
|
||||
void CYSFNetwork::link()
|
||||
{
|
||||
if (m_state != DS_NOTLINKED)
|
||||
if (m_state != DGID_STATUS::NOTLINKED)
|
||||
return;
|
||||
|
||||
m_state = DS_LINKING;
|
||||
m_state = DGID_STATUS::LINKING;
|
||||
|
||||
m_sendPollTimer.start();
|
||||
m_recvPollTimer.start();
|
||||
|
|
@ -154,7 +154,7 @@ void CYSFNetwork::link()
|
|||
|
||||
void CYSFNetwork::writePoll()
|
||||
{
|
||||
if (m_state != DS_LINKING && m_state != DS_LINKED)
|
||||
if (m_state != DGID_STATUS::LINKING && m_state != DGID_STATUS::LINKED)
|
||||
return;
|
||||
|
||||
if (m_debug)
|
||||
|
|
@ -165,7 +165,7 @@ void CYSFNetwork::writePoll()
|
|||
|
||||
void CYSFNetwork::unlink()
|
||||
{
|
||||
if (m_state != DS_LINKED)
|
||||
if (m_state != DGID_STATUS::LINKED)
|
||||
return;
|
||||
|
||||
m_sendPollTimer.stop();
|
||||
|
|
@ -178,20 +178,20 @@ void CYSFNetwork::unlink()
|
|||
|
||||
LogMessage("Unlinked from %s", m_name.c_str());
|
||||
|
||||
m_state = DS_NOTLINKED;
|
||||
m_state = DGID_STATUS::NOTLINKED;
|
||||
}
|
||||
|
||||
void CYSFNetwork::clock(unsigned int ms)
|
||||
{
|
||||
if (m_state == DS_NOTOPEN)
|
||||
if (m_state == DGID_STATUS::NOTOPEN)
|
||||
return;
|
||||
|
||||
m_recvPollTimer.clock(ms);
|
||||
if (m_recvPollTimer.isRunning() && m_recvPollTimer.hasExpired()) {
|
||||
if (m_static) {
|
||||
m_state = DS_LINKING;
|
||||
m_state = DGID_STATUS::LINKING;
|
||||
} else {
|
||||
m_state = DS_NOTLINKED;
|
||||
m_state = DGID_STATUS::NOTLINKED;
|
||||
m_sendPollTimer.stop();
|
||||
}
|
||||
|
||||
|
|
@ -224,13 +224,13 @@ void CYSFNetwork::clock(unsigned int ms)
|
|||
if (::memcmp(buffer, "YSFP", 4U) == 0) {
|
||||
m_recvPollTimer.start();
|
||||
|
||||
if (m_state == DS_LINKING) {
|
||||
if (m_state == DGID_STATUS::LINKING) {
|
||||
if (strcmp(m_name.c_str(), "MMDVM") == 0)
|
||||
LogMessage("Link successful to %s", m_name.c_str());
|
||||
else
|
||||
LogMessage("Linked to %s", m_name.c_str());
|
||||
|
||||
m_state = DS_LINKED;
|
||||
m_state = DGID_STATUS::LINKED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ void CYSFNetwork::clock(unsigned int ms)
|
|||
|
||||
unsigned int CYSFNetwork::read(unsigned int dgid, unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_buffer.isEmpty())
|
||||
return 0U;
|
||||
|
|
@ -265,5 +265,5 @@ void CYSFNetwork::close()
|
|||
|
||||
LogMessage("Closing YSF network connection");
|
||||
|
||||
m_state = DS_NOTOPEN;
|
||||
m_state = DGID_STATUS::NOTOPEN;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2020 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2016,2020,2025 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -86,8 +86,8 @@ CYSFPayload::~CYSFPayload()
|
|||
|
||||
bool CYSFPayload::readHeaderData(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -154,8 +154,8 @@ bool CYSFPayload::readHeaderData(const unsigned char* data, unsigned char* dt)
|
|||
|
||||
bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -195,8 +195,8 @@ bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
|||
|
||||
bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -236,8 +236,8 @@ bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
|||
|
||||
bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
|
||||
|
|
@ -279,8 +279,8 @@ bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char*
|
|||
|
||||
bool CYSFPayload::readVoiceFRModeData(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -314,8 +314,8 @@ bool CYSFPayload::readVoiceFRModeData(const unsigned char* data, unsigned char*
|
|||
|
||||
bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
|
||||
|
|
@ -357,8 +357,8 @@ bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char*
|
|||
|
||||
void CYSFPayload::writeHeaderData(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -374,7 +374,7 @@ void CYSFPayload::writeHeaderData(const unsigned char* dt, unsigned char* data)
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned char bytes[45U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
|
@ -431,8 +431,8 @@ void CYSFPayload::writeHeaderData(const unsigned char* dt, unsigned char* data)
|
|||
|
||||
void CYSFPayload::writeVDMode1Data(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -448,7 +448,7 @@ void CYSFPayload::writeVDMode1Data(const unsigned char* dt, unsigned char* data)
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned char bytes[45U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
|
@ -475,8 +475,8 @@ void CYSFPayload::writeVDMode1Data(const unsigned char* dt, unsigned char* data)
|
|||
|
||||
void CYSFPayload::writeVDMode2Data(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -492,7 +492,7 @@ void CYSFPayload::writeVDMode2Data(const unsigned char* dt, unsigned char* data)
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 100U);
|
||||
|
||||
unsigned char bytes[25U];
|
||||
unsigned char bytes[25U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_5_20[i];
|
||||
|
|
@ -519,8 +519,8 @@ void CYSFPayload::writeVDMode2Data(const unsigned char* dt, unsigned char* data)
|
|||
|
||||
void CYSFPayload::writeVoiceFRModeData(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -536,7 +536,7 @@ void CYSFPayload::writeVoiceFRModeData(const unsigned char* dt, unsigned char* d
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned char bytes[45U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
|
@ -558,8 +558,8 @@ void CYSFPayload::writeVoiceFRModeData(const unsigned char* dt, unsigned char* d
|
|||
|
||||
void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -575,7 +575,7 @@ void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* d
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned char bytes[45U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
|
@ -602,8 +602,8 @@ void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* d
|
|||
|
||||
void CYSFPayload::writeDataFRModeData2(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -619,7 +619,7 @@ void CYSFPayload::writeDataFRModeData2(const unsigned char* dt, unsigned char* d
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned char bytes[45U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016-2020,2025 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
|
||||
|
|
@ -43,24 +43,24 @@ CYSFReflectors::~CYSFReflectors()
|
|||
bool CYSFReflectors::load()
|
||||
{
|
||||
FILE* fp = ::fopen(m_hostsFile.c_str(), "rt");
|
||||
if (fp != NULL) {
|
||||
if (fp != nullptr) {
|
||||
char buffer[100U];
|
||||
while (::fgets(buffer, 100U, fp) != NULL) {
|
||||
while (::fgets(buffer, 100U, fp) != nullptr) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
char* p1 = ::strtok(buffer, ";\r\n");
|
||||
char* p2 = ::strtok(NULL, ";\r\n");
|
||||
char* p3 = ::strtok(NULL, ";\r\n");
|
||||
char* p4 = ::strtok(NULL, ";\r\n");
|
||||
char* p5 = ::strtok(NULL, ";\r\n");
|
||||
char* p6 = ::strtok(NULL, "\r\n");
|
||||
char* p2 = ::strtok(nullptr, ";\r\n");
|
||||
char* p3 = ::strtok(nullptr, ";\r\n");
|
||||
char* p4 = ::strtok(nullptr, ";\r\n");
|
||||
char* p5 = ::strtok(nullptr, ";\r\n");
|
||||
char* p6 = ::strtok(nullptr, "\r\n");
|
||||
|
||||
if (p1 != NULL && p2 != NULL && p3 != NULL && p4 != NULL && p5 != NULL && p6 != NULL) {
|
||||
if (p1 != nullptr && p2 != nullptr && p3 != nullptr && p4 != nullptr && p5 != nullptr && p6 != nullptr) {
|
||||
std::string host = std::string(p4);
|
||||
unsigned short port = (unsigned short)::atoi(p5);
|
||||
|
||||
if (::strstr(p1, "YCS") == NULL && ::strstr(p2, "YCS") == NULL) {
|
||||
if (::strstr(p1, "YCS") == nullptr && ::strstr(p2, "YCS") == nullptr) {
|
||||
sockaddr_storage addr;
|
||||
unsigned int addrLen;
|
||||
if (CUDPSocket::lookup(host, port, addr, addrLen) == 0) {
|
||||
|
|
@ -95,7 +95,7 @@ CYSFReflector* CYSFReflectors::findById(const std::string& id)
|
|||
|
||||
LogMessage("Trying to find non existent YSF reflector with an id of %s", id.c_str());
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CYSFReflector* CYSFReflectors::findByName(const std::string& name)
|
||||
|
|
@ -107,6 +107,6 @@ CYSFReflector* CYSFReflectors::findByName(const std::string& name)
|
|||
|
||||
LogMessage("Trying to find non existent YSF reflector with a name of %s", name.c_str());
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
38
DGIdGateway/prebuild.cmd
Normal file
38
DGIdGateway/prebuild.cmd
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
@echo off
|
||||
REM This pre-build file is for MSVS VC++. It parses the git master hash and
|
||||
REM converts it into GitVersion.h for compiling into builds. [George M1GEO]
|
||||
|
||||
cd %1
|
||||
setlocal enabledelayedexpansion
|
||||
set HEADFILE=..\.git\HEAD
|
||||
set HASHFILE=0
|
||||
if exist %HEADFILE% (
|
||||
for /F "tokens=4 delims=/:" %%a in ('type %HEADFILE%') do set HEADBRANCH=%%a
|
||||
set HASHFILE=..\.git\refs\heads\!HEADBRANCH!
|
||||
echo Found Git HEAD file: %HEADFILE%
|
||||
echo Git HEAD branch: !HEADBRANCH!
|
||||
echo Git HASH file: !HASHFILE!
|
||||
call :USEHASH
|
||||
) else (
|
||||
echo No head file :(
|
||||
call :USENULL
|
||||
)
|
||||
|
||||
goto :EOF
|
||||
|
||||
:USENULL
|
||||
set GITHASH=0000000000000000000000000000000000000000
|
||||
goto :WRITEGITVERSIONHEADER
|
||||
|
||||
:USEHASH
|
||||
for /f %%i in ('type !HASHFILE!') do set GITHASH=%%i
|
||||
goto :WRITEGITVERSIONHEADER
|
||||
|
||||
:WRITEGITVERSIONHEADER
|
||||
echo // File contains Git commit ID SHA1 present at buildtime (prebuild.cmd) > GitVersion.h
|
||||
echo const char *gitversion = "%GITHASH%"; >> GitVersion.h
|
||||
echo Current Git HASH: %GITHASH%
|
||||
goto :FINISHED
|
||||
|
||||
:FINISHED
|
||||
echo GitVersion.h written...
|
||||
|
|
@ -10,6 +10,8 @@ The Gateways have ini files that contain the parameters for running the software
|
|||
|
||||
The MMDVM .ini file should have the IP address and port number of the client in the [System Fusion Network] settings.
|
||||
|
||||
The file that contains the information about the reachable YSF reflectors is held in the YSFHosts.txt files that should be donwloaded from the DVRef.com web site. A script to do this under Linux is included. This is handled automatically in WPSD and Pi-Star.
|
||||
|
||||
They build on 32-bit and 64-bit Linux as well as on Windows using Visual Studio 2019 on x86 and x64.
|
||||
|
||||
This software is licenced under the GPL v2 and is primarily intended for amateur and educational use.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2010-2014,2016,2017,2018,2020,2025 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
|
||||
|
|
@ -106,7 +106,7 @@ bool CAPRSWriter::open()
|
|||
return false;
|
||||
}
|
||||
|
||||
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL);
|
||||
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, nullptr);
|
||||
|
||||
LogMessage("Connected to GPSD");
|
||||
}
|
||||
|
|
@ -125,8 +125,8 @@ bool CAPRSWriter::open()
|
|||
|
||||
void CAPRSWriter::write(const unsigned char* source, const char* type, unsigned char radio, float fLatitude, float fLongitude)
|
||||
{
|
||||
assert(source != NULL);
|
||||
assert(type != NULL);
|
||||
assert(source != nullptr);
|
||||
assert(type != nullptr);
|
||||
|
||||
char callsign[15U];
|
||||
::memcpy(callsign, source, YSF_CALLSIGN_LENGTH);
|
||||
|
|
@ -219,7 +219,7 @@ void CAPRSWriter::close()
|
|||
|
||||
#if defined(USE_GPSD)
|
||||
if (m_gpsdEnabled) {
|
||||
::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL);
|
||||
::gps_stream(&m_gpsdData, WATCH_DISABLE, nullptr);
|
||||
::gps_close(&m_gpsdData);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -300,7 +300,7 @@ void CAPRSWriter::sendIdFrameMobile()
|
|||
return;
|
||||
|
||||
#if GPSD_API_MAJOR_VERSION >= 7
|
||||
if (::gps_read(&m_gpsdData, NULL, 0) <= 0)
|
||||
if (::gps_read(&m_gpsdData, nullptr, 0) <= 0)
|
||||
return;
|
||||
#else
|
||||
if (::gps_read(&m_gpsdData) <= 0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2025 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
|
||||
|
|
@ -63,7 +63,7 @@ const uint16_t CCITT16_TABLE2[] = {
|
|||
|
||||
void CCRC::addCCITT16(unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(in != nullptr);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
|
|
@ -84,7 +84,7 @@ void CCRC::addCCITT16(unsigned char *in, unsigned int length)
|
|||
|
||||
bool CCRC::checkCCITT16(const unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(in != nullptr);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
|
|
@ -104,7 +104,7 @@ bool CCRC::checkCCITT16(const unsigned char *in, unsigned int length)
|
|||
|
||||
unsigned char CCRC::addCRC(const unsigned char* in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(in != nullptr);
|
||||
|
||||
unsigned char crc = 0U;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2020,2025 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
|
||||
|
|
@ -26,17 +26,17 @@
|
|||
|
||||
const int BUFFER_SIZE = 500;
|
||||
|
||||
enum SECTION {
|
||||
SECTION_NONE,
|
||||
SECTION_GENERAL,
|
||||
SECTION_INFO,
|
||||
SECTION_LOG,
|
||||
SECTION_APRS,
|
||||
SECTION_NETWORK,
|
||||
SECTION_YSF_NETWORK,
|
||||
SECTION_FCS_NETWORK,
|
||||
SECTION_GPSD,
|
||||
SECTION_REMOTE_COMMANDS
|
||||
enum class SECTION {
|
||||
NONE,
|
||||
GENERAL,
|
||||
INFO,
|
||||
LOG,
|
||||
APRS,
|
||||
NETWORK,
|
||||
YSF_NETWORK,
|
||||
FCS_NETWORK,
|
||||
GPSD,
|
||||
REMOTE_COMMANDS
|
||||
};
|
||||
|
||||
CConf::CConf(const std::string& file) :
|
||||
|
|
@ -48,7 +48,6 @@ m_rptAddress(),
|
|||
m_rptPort(0U),
|
||||
m_myAddress(),
|
||||
m_myPort(0U),
|
||||
m_wiresXMakeUpper(true),
|
||||
m_wiresXCommandPassthrough(false),
|
||||
m_debug(false),
|
||||
m_daemon(false),
|
||||
|
|
@ -60,7 +59,6 @@ m_longitude(0.0F),
|
|||
m_height(0),
|
||||
m_name(),
|
||||
m_description(),
|
||||
m_aprsSymbol(),
|
||||
m_logDisplayLevel(0U),
|
||||
m_logFileLevel(0U),
|
||||
m_logFilePath(),
|
||||
|
|
@ -71,9 +69,11 @@ m_aprsAddress(),
|
|||
m_aprsPort(0U),
|
||||
m_aprsSuffix(),
|
||||
m_aprsDescription(),
|
||||
m_aprsSymbol("/r"),
|
||||
m_networkStartup(),
|
||||
m_networkOptions(),
|
||||
m_networkInactivityTimeout(0U),
|
||||
m_networkReconnect(false),
|
||||
m_networkRevert(false),
|
||||
m_networkDebug(false),
|
||||
m_ysfNetworkEnabled(false),
|
||||
|
|
@ -106,49 +106,49 @@ CConf::~CConf()
|
|||
bool CConf::read()
|
||||
{
|
||||
FILE* fp = ::fopen(m_file.c_str(), "rt");
|
||||
if (fp == NULL) {
|
||||
if (fp == nullptr) {
|
||||
::fprintf(stderr, "Couldn't open the .ini file - %s\n", m_file.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
SECTION section = SECTION_NONE;
|
||||
SECTION section = SECTION::NONE;
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) {
|
||||
while (::fgets(buffer, BUFFER_SIZE, fp) != nullptr) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
if (buffer[0U] == '[') {
|
||||
if (::strncmp(buffer, "[General]", 9U) == 0)
|
||||
section = SECTION_GENERAL;
|
||||
section = SECTION::GENERAL;
|
||||
else if (::strncmp(buffer, "[Info]", 6U) == 0)
|
||||
section = SECTION_INFO;
|
||||
section = SECTION::INFO;
|
||||
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
||||
section = SECTION_LOG;
|
||||
section = SECTION::LOG;
|
||||
else if (::strncmp(buffer, "[APRS]", 6U) == 0)
|
||||
section = SECTION_APRS;
|
||||
section = SECTION::APRS;
|
||||
else if (::strncmp(buffer, "[Network]", 9U) == 0)
|
||||
section = SECTION_NETWORK;
|
||||
section = SECTION::NETWORK;
|
||||
else if (::strncmp(buffer, "[YSF Network]", 13U) == 0)
|
||||
section = SECTION_YSF_NETWORK;
|
||||
section = SECTION::YSF_NETWORK;
|
||||
else if (::strncmp(buffer, "[FCS Network]", 13U) == 0)
|
||||
section = SECTION_FCS_NETWORK;
|
||||
section = SECTION::FCS_NETWORK;
|
||||
else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
|
||||
section = SECTION_GPSD;
|
||||
section = SECTION::GPSD;
|
||||
else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0)
|
||||
section = SECTION_REMOTE_COMMANDS;
|
||||
section = SECTION::REMOTE_COMMANDS;
|
||||
else
|
||||
section = SECTION_NONE;
|
||||
section = SECTION::NONE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
char* key = ::strtok(buffer, " \t=\r\n");
|
||||
if (key == NULL)
|
||||
if (key == nullptr)
|
||||
continue;
|
||||
|
||||
char* value = ::strtok(NULL, "\r\n");
|
||||
if (value == NULL)
|
||||
char* value = ::strtok(nullptr, "\r\n");
|
||||
if (value == nullptr)
|
||||
continue;
|
||||
|
||||
// Remove quotes from the value
|
||||
|
|
@ -160,7 +160,7 @@ bool CConf::read()
|
|||
char *p;
|
||||
|
||||
// if value is not quoted, remove after # (to make comment)
|
||||
if ((p = strchr(value, '#')) != NULL)
|
||||
if ((p = strchr(value, '#')) != nullptr)
|
||||
*p = '\0';
|
||||
|
||||
// remove trailing tab/space
|
||||
|
|
@ -168,7 +168,7 @@ bool CConf::read()
|
|||
*p = '\0';
|
||||
}
|
||||
|
||||
if (section == SECTION_GENERAL) {
|
||||
if (section == SECTION::GENERAL) {
|
||||
if (::strcmp(key, "Callsign") == 0) {
|
||||
// Convert the callsign to upper case
|
||||
for (unsigned int i = 0U; value[i] != 0; i++)
|
||||
|
|
@ -189,15 +189,13 @@ bool CConf::read()
|
|||
m_myAddress = value;
|
||||
else if (::strcmp(key, "LocalPort") == 0)
|
||||
m_myPort = (unsigned short)::atoi(value);
|
||||
else if (::strcmp(key, "WiresXMakeUpper") == 0)
|
||||
m_wiresXMakeUpper = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "WiresXCommandPassthrough") == 0)
|
||||
m_wiresXCommandPassthrough = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_debug = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Daemon") == 0)
|
||||
m_daemon = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_INFO) {
|
||||
} else if (section == SECTION::INFO) {
|
||||
if (::strcmp(key, "TXFrequency") == 0)
|
||||
m_txFrequency = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "RXFrequency") == 0)
|
||||
|
|
@ -214,7 +212,7 @@ bool CConf::read()
|
|||
m_name = value;
|
||||
else if (::strcmp(key, "Description") == 0)
|
||||
m_description = value;
|
||||
} else if (section == SECTION_LOG) {
|
||||
} else if (section == SECTION::LOG) {
|
||||
if (::strcmp(key, "FilePath") == 0)
|
||||
m_logFilePath = value;
|
||||
else if (::strcmp(key, "FileRoot") == 0)
|
||||
|
|
@ -225,7 +223,7 @@ bool CConf::read()
|
|||
m_logDisplayLevel = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "FileRotate") == 0)
|
||||
m_logFileRotate = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_APRS) {
|
||||
} else if (section == SECTION::APRS) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_aprsEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Address") == 0)
|
||||
|
|
@ -238,18 +236,20 @@ bool CConf::read()
|
|||
m_aprsDescription = value;
|
||||
else if (::strcmp(key, "Symbol") == 0)
|
||||
m_aprsSymbol = value;
|
||||
} else if (section == SECTION_NETWORK) {
|
||||
} else if (section == SECTION::NETWORK) {
|
||||
if (::strcmp(key, "Startup") == 0)
|
||||
m_networkStartup = value;
|
||||
else if (::strcmp(key, "Options") == 0)
|
||||
m_networkOptions = value;
|
||||
else if (::strcmp(key, "InactivityTimeout") == 0)
|
||||
m_networkInactivityTimeout = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Reconnect") == 0)
|
||||
m_networkReconnect = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Revert") == 0)
|
||||
m_networkRevert = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_networkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_YSF_NETWORK) {
|
||||
} else if (section == SECTION::YSF_NETWORK) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_ysfNetworkEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Port") == 0)
|
||||
|
|
@ -274,21 +274,21 @@ bool CConf::read()
|
|||
m_ysfNetworkYSF2P25Address = value;
|
||||
else if (::strcmp(key, "YSF2P25Port") == 0)
|
||||
m_ysfNetworkYSF2P25Port = (unsigned short)::atoi(value);
|
||||
} else if (section == SECTION_FCS_NETWORK) {
|
||||
} else if (section == SECTION::FCS_NETWORK) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_fcsNetworkEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Rooms") == 0)
|
||||
m_fcsNetworkFile = value;
|
||||
else if (::strcmp(key, "Port") == 0)
|
||||
m_fcsNetworkPort = (unsigned short)::atoi(value);
|
||||
} else if (section == SECTION_GPSD) {
|
||||
} else if (section == SECTION::GPSD) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_gpsdEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Address") == 0)
|
||||
m_gpsdAddress = value;
|
||||
else if (::strcmp(key, "Port") == 0)
|
||||
m_gpsdPort = value;
|
||||
} else if (section == SECTION_REMOTE_COMMANDS) {
|
||||
} else if (section == SECTION::REMOTE_COMMANDS) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_remoteCommandsEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Port") == 0)
|
||||
|
|
@ -336,11 +336,6 @@ unsigned short CConf::getMyPort() const
|
|||
return m_myPort;
|
||||
}
|
||||
|
||||
bool CConf::getWiresXMakeUpper() const
|
||||
{
|
||||
return m_wiresXMakeUpper;
|
||||
}
|
||||
|
||||
bool CConf::getWiresXCommandPassthrough() const
|
||||
{
|
||||
return m_wiresXCommandPassthrough;
|
||||
|
|
@ -466,6 +461,11 @@ unsigned int CConf::getNetworkInactivityTimeout() const
|
|||
return m_networkInactivityTimeout;
|
||||
}
|
||||
|
||||
bool CConf::getNetworkReconnect() const
|
||||
{
|
||||
return m_networkReconnect;
|
||||
}
|
||||
|
||||
bool CConf::getNetworkRevert() const
|
||||
{
|
||||
return m_networkRevert;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ public:
|
|||
unsigned short getRptPort() const;
|
||||
std::string getMyAddress() const;
|
||||
unsigned short getMyPort() const;
|
||||
bool getWiresXMakeUpper() const;
|
||||
bool getWiresXCommandPassthrough() const;
|
||||
bool getDebug() const;
|
||||
bool getDaemon() const;
|
||||
|
|
@ -71,6 +70,7 @@ public:
|
|||
std::string getNetworkStartup() const;
|
||||
std::string getNetworkOptions() const;
|
||||
unsigned int getNetworkInactivityTimeout() const;
|
||||
bool getNetworkReconnect() const;
|
||||
bool getNetworkRevert() const;
|
||||
bool getNetworkDebug() const;
|
||||
|
||||
|
|
@ -111,7 +111,6 @@ private:
|
|||
unsigned short m_rptPort;
|
||||
std::string m_myAddress;
|
||||
unsigned short m_myPort;
|
||||
bool m_wiresXMakeUpper;
|
||||
bool m_wiresXCommandPassthrough;
|
||||
bool m_debug;
|
||||
bool m_daemon;
|
||||
|
|
@ -141,6 +140,7 @@ private:
|
|||
std::string m_networkStartup;
|
||||
std::string m_networkOptions;
|
||||
unsigned int m_networkInactivityTimeout;
|
||||
bool m_networkReconnect;
|
||||
bool m_networkRevert;
|
||||
bool m_networkDebug;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012,2013,2015,2017,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2012,2013,2015,2017,2018,2025 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2011 by DV Developer Group. DJ0ABR
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -60,17 +60,17 @@ CDTMF::~CDTMF()
|
|||
|
||||
WX_STATUS CDTMF::decodeVDMode2(unsigned char* payload, bool end)
|
||||
{
|
||||
assert(payload != NULL);
|
||||
assert(payload != nullptr);
|
||||
|
||||
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)
|
||||
if (status != WX_STATUS::NONE)
|
||||
return status;
|
||||
}
|
||||
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
WX_STATUS CDTMF::decodeVDMode2Slice(unsigned char* ambe, bool end)
|
||||
|
|
@ -167,43 +167,43 @@ WX_STATUS CDTMF::decodeVDMode2Slice(unsigned char* ambe, bool end)
|
|||
WX_STATUS CDTMF::validate() const
|
||||
{
|
||||
if (m_command.empty())
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
|
||||
size_t length = m_command.length();
|
||||
char first = m_command.at(0U);
|
||||
|
||||
if (length == 1U && first == '#') {
|
||||
return WXS_DISCONNECT;
|
||||
return WX_STATUS::DISCONNECT;
|
||||
} else if (length == 3U && first == 'A') {
|
||||
for (unsigned int i = 1U; i < 3U; i++) {
|
||||
char c = m_command.at(i);
|
||||
if (c < '0' || c > '9')
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
return WXS_CONNECT_FCS;
|
||||
return WX_STATUS::CONNECT_FCS;
|
||||
} else if (length == 4U && first == 'A') {
|
||||
for (unsigned int i = 1U; i < 4U; i++) {
|
||||
char c = m_command.at(i);
|
||||
if (c < '0' || c > '9')
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
return WXS_CONNECT_FCS;
|
||||
return WX_STATUS::CONNECT_FCS;
|
||||
} else if (length == 6U && first == '#') {
|
||||
for (unsigned int i = 1U; i < 6U; i++) {
|
||||
char c = m_command.at(i);
|
||||
if (c < '0' || c > '9')
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
if (m_command == "#99999")
|
||||
return WXS_DISCONNECT;
|
||||
return WX_STATUS::DISCONNECT;
|
||||
|
||||
return WXS_CONNECT_YSF;
|
||||
return WX_STATUS::CONNECT_YSF;
|
||||
}
|
||||
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
std::string CDTMF::getReflector()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020,2025 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,17 +34,17 @@ m_socket(port),
|
|||
m_debug(debug),
|
||||
m_addr(),
|
||||
m_addrLen(),
|
||||
m_ping(NULL),
|
||||
m_options(NULL),
|
||||
m_ping(nullptr),
|
||||
m_options(nullptr),
|
||||
m_opt(),
|
||||
m_info(NULL),
|
||||
m_info(nullptr),
|
||||
m_reflector(),
|
||||
m_print(),
|
||||
m_buffer(1000U, "FCS Network Buffer"),
|
||||
m_n(0U),
|
||||
m_pingTimer(1000U, 0U, 800U),
|
||||
m_resetTimer(1000U, 1U),
|
||||
m_state(FCS_UNLINKED)
|
||||
m_state(FCS_STATE::UNLINKED)
|
||||
{
|
||||
m_info = new unsigned char[100U];
|
||||
::sprintf((char*)m_info, "%9u%9u%-6.6s%-12.12s%7u", rxFrequency, txFrequency, locator.c_str(), FCS_VERSION, id);
|
||||
|
|
@ -93,14 +93,14 @@ void CFCSNetwork::clearDestination()
|
|||
m_pingTimer.stop();
|
||||
m_resetTimer.stop();
|
||||
|
||||
m_state = FCS_UNLINKED;
|
||||
m_state = FCS_STATE::UNLINKED;
|
||||
}
|
||||
|
||||
void CFCSNetwork::write(const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_state != FCS_LINKED)
|
||||
if (m_state != FCS_STATE::LINKED)
|
||||
return;
|
||||
|
||||
unsigned char buffer[130U];
|
||||
|
|
@ -117,7 +117,7 @@ void CFCSNetwork::write(const unsigned char* data)
|
|||
|
||||
bool CFCSNetwork::writeLink(const std::string& reflector)
|
||||
{
|
||||
if (m_state != FCS_LINKED) {
|
||||
if (m_state != FCS_STATE::LINKED) {
|
||||
std::string name = reflector.substr(0U, 6U);
|
||||
|
||||
if (m_addresses.count(name) == 0U) {
|
||||
|
|
@ -140,7 +140,7 @@ bool CFCSNetwork::writeLink(const std::string& reflector)
|
|||
|
||||
m_print = reflector.substr(0U, 6U) + "-" + reflector.substr(6U);
|
||||
|
||||
m_state = FCS_LINKING;
|
||||
m_state = FCS_STATE::LINKING;
|
||||
|
||||
m_pingTimer.start();
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ void CFCSNetwork::setOptions(const std::string& options)
|
|||
|
||||
void CFCSNetwork::writeUnlink(unsigned int count)
|
||||
{
|
||||
if (m_state != FCS_LINKED)
|
||||
if (m_state != FCS_STATE::LINKED)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0U; i < count; i++)
|
||||
|
|
@ -185,7 +185,7 @@ void CFCSNetwork::clock(unsigned int ms)
|
|||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (m_state == FCS_UNLINKED)
|
||||
if (m_state == FCS_STATE::UNLINKED)
|
||||
return;
|
||||
|
||||
if (!CUDPSocket::match(addr, m_addr))
|
||||
|
|
@ -195,16 +195,16 @@ void CFCSNetwork::clock(unsigned int ms)
|
|||
CUtils::dump(1U, "FCS Network Data Received", buffer, length);
|
||||
|
||||
if (length == 7) {
|
||||
if (m_state == FCS_LINKING)
|
||||
if (m_state == FCS_STATE::LINKING)
|
||||
LogMessage("Linked to %s", m_print.c_str());
|
||||
m_state = FCS_LINKED;
|
||||
m_state = FCS_STATE::LINKED;
|
||||
writeInfo();
|
||||
writeOptions(m_print);
|
||||
}
|
||||
|
||||
if (length == 10 && m_state == FCS_LINKING) {
|
||||
if (length == 10 && m_state == FCS_STATE::LINKING) {
|
||||
LogMessage("Linked to %s", m_print.c_str());
|
||||
m_state = FCS_LINKED;
|
||||
m_state = FCS_STATE::LINKED;
|
||||
writeInfo();
|
||||
writeOptions(m_print);
|
||||
}
|
||||
|
|
@ -218,7 +218,7 @@ void CFCSNetwork::clock(unsigned int ms)
|
|||
|
||||
unsigned int CFCSNetwork::read(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_buffer.isEmpty())
|
||||
return 0U;
|
||||
|
|
@ -264,7 +264,7 @@ void CFCSNetwork::close()
|
|||
|
||||
void CFCSNetwork::writeInfo()
|
||||
{
|
||||
if (m_state != FCS_LINKED)
|
||||
if (m_state != FCS_STATE::LINKED)
|
||||
return;
|
||||
|
||||
if (m_debug)
|
||||
|
|
@ -275,7 +275,7 @@ void CFCSNetwork::writeInfo()
|
|||
|
||||
void CFCSNetwork::writePing()
|
||||
{
|
||||
if (m_state == FCS_UNLINKED)
|
||||
if (m_state == FCS_STATE::UNLINKED)
|
||||
return;
|
||||
|
||||
if (m_debug)
|
||||
|
|
@ -286,7 +286,7 @@ void CFCSNetwork::writePing()
|
|||
|
||||
void CFCSNetwork::writeOptions(const std::string& reflector)
|
||||
{
|
||||
if (m_state != FCS_LINKED)
|
||||
if (m_state != FCS_STATE::LINKED)
|
||||
return;
|
||||
|
||||
if (m_opt.size() < 1)
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
|
||||
enum FCS_STATE {
|
||||
FCS_UNLINKED,
|
||||
FCS_LINKING,
|
||||
FCS_LINKED
|
||||
enum class FCS_STATE {
|
||||
UNLINKED,
|
||||
LINKING,
|
||||
LINKED
|
||||
};
|
||||
|
||||
class CFCSNetwork {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2018,2020,2024,2025 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
|
||||
|
|
@ -32,10 +32,10 @@ const unsigned char LONG_GPS[] = {0x47U, 0x64U};
|
|||
|
||||
CGPS::CGPS(CAPRSWriter* writer) :
|
||||
m_writer(writer),
|
||||
m_buffer(NULL),
|
||||
m_buffer(nullptr),
|
||||
m_sent(false)
|
||||
{
|
||||
assert(writer != NULL);
|
||||
assert(writer != nullptr);
|
||||
|
||||
m_buffer = new unsigned char[300U];
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ void CGPS::reset()
|
|||
|
||||
void CGPS::transmitGPS(const unsigned char* source)
|
||||
{
|
||||
assert(m_writer != NULL);
|
||||
assert(m_writer != nullptr);
|
||||
|
||||
// We don't know who its from!
|
||||
if (::memcmp(source, " ", YSF_CALLSIGN_LENGTH) == 0)
|
||||
|
|
@ -258,6 +258,9 @@ void CGPS::transmitGPS(const unsigned char* source)
|
|||
case 0x26U:
|
||||
::strcpy(radio, "DR-1X");
|
||||
break;
|
||||
case 0x27U:
|
||||
::strcpy(radio, "FT-991A");
|
||||
break;
|
||||
case 0x28U:
|
||||
::strcpy(radio, "FT-2D");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2010,2016,2025 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2002 by Robert H. Morelos-Zaragoza. All rights reserved.
|
||||
*/
|
||||
|
||||
|
|
@ -1096,7 +1096,7 @@ unsigned int CGolay24128::decode24128(unsigned int code)
|
|||
|
||||
unsigned int CGolay24128::decode24128(unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
assert(bytes != nullptr);
|
||||
|
||||
unsigned int code = bytes[0U];
|
||||
code <<= 8;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2020,2025 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
|
||||
|
|
@ -37,7 +37,7 @@ static std::string m_filePath;
|
|||
static std::string m_fileRoot;
|
||||
static bool m_fileRotate = true;
|
||||
|
||||
static FILE* m_fpLog = NULL;
|
||||
static FILE* m_fpLog = nullptr;
|
||||
static bool m_daemon = false;
|
||||
|
||||
static unsigned int m_displayLevel = 2U;
|
||||
|
|
@ -59,10 +59,10 @@ static bool logOpenRotate()
|
|||
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)
|
||||
if (m_fpLog != nullptr)
|
||||
return true;
|
||||
} else {
|
||||
if (m_fpLog != NULL)
|
||||
if (m_fpLog != nullptr)
|
||||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ static bool logOpenRotate()
|
|||
::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) {
|
||||
if ((m_fpLog = ::fopen(filename, "a+t")) != nullptr) {
|
||||
status = true;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
|
|
@ -94,7 +94,7 @@ static bool logOpenNoRotate()
|
|||
if (m_fileLevel == 0U)
|
||||
return true;
|
||||
|
||||
if (m_fpLog != NULL)
|
||||
if (m_fpLog != nullptr)
|
||||
return true;
|
||||
|
||||
char filename[200U];
|
||||
|
|
@ -104,7 +104,7 @@ static bool logOpenNoRotate()
|
|||
::sprintf(filename, "%s/%s.log", m_filePath.c_str(), m_fileRoot.c_str());
|
||||
#endif
|
||||
|
||||
if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) {
|
||||
if ((m_fpLog = ::fopen(filename, "a+t")) != nullptr) {
|
||||
status = true;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
|
|
@ -141,13 +141,13 @@ bool LogInitialise(bool daemon, const std::string& filePath, const std::string&
|
|||
|
||||
void LogFinalise()
|
||||
{
|
||||
if (m_fpLog != NULL)
|
||||
if (m_fpLog != nullptr)
|
||||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
void Log(unsigned int level, const char* fmt, ...)
|
||||
{
|
||||
assert(fmt != NULL);
|
||||
assert(fmt != nullptr);
|
||||
|
||||
char buffer[501U];
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -157,7 +157,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
|||
::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);
|
||||
::gettimeofday(&now, nullptr);
|
||||
|
||||
struct tm* tm = ::gmtime(&now.tv_sec);
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
|||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
|
||||
::vsnprintf(buffer + ::strlen(buffer), 500, fmt, vl);
|
||||
::vsnprintf(buffer + ::strlen(buffer), 500 - ::strlen(buffer), fmt, vl);
|
||||
|
||||
va_end(vl);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2009,2012,2013,2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2006-2009,2012,2013,2015,2016,2025 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,12 +30,12 @@ public:
|
|||
CRingBuffer(unsigned int length, const char* name) :
|
||||
m_length(length),
|
||||
m_name(name),
|
||||
m_buffer(NULL),
|
||||
m_buffer(nullptr),
|
||||
m_iPtr(0U),
|
||||
m_oPtr(0U)
|
||||
{
|
||||
assert(length > 0U);
|
||||
assert(name != NULL);
|
||||
assert(name != nullptr);
|
||||
|
||||
m_buffer = new T[length];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2018,2025 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
|
||||
|
|
@ -77,7 +77,7 @@ CStopWatch::~CStopWatch()
|
|||
unsigned long long CStopWatch::time() const
|
||||
{
|
||||
struct timeval now;
|
||||
::gettimeofday(&now, NULL);
|
||||
::gettimeofday(&now, nullptr);
|
||||
|
||||
return now.tv_sec * 1000ULL + now.tv_usec / 1000ULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2025 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
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
void CSync::add(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
::memcpy(data, YSF_SYNC_BYTES, YSF_SYNC_LENGTH_BYTES);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2020,2025 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,9 +31,9 @@ CThread::~CThread()
|
|||
|
||||
bool CThread::run()
|
||||
{
|
||||
m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL);
|
||||
m_handle = ::CreateThread(nullptr, 0, &helper, this, 0, nullptr);
|
||||
|
||||
return m_handle != NULL;
|
||||
return m_handle != nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -74,13 +74,13 @@ CThread::~CThread()
|
|||
|
||||
bool CThread::run()
|
||||
{
|
||||
return ::pthread_create(&m_thread, NULL, helper, this) == 0;
|
||||
return ::pthread_create(&m_thread, nullptr, helper, this) == 0;
|
||||
}
|
||||
|
||||
|
||||
void CThread::wait()
|
||||
{
|
||||
::pthread_join(m_thread, NULL);
|
||||
::pthread_join(m_thread, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ void* CThread::helper(void* arg)
|
|||
|
||||
p->entry();
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CThread::sleep(unsigned int ms)
|
||||
|
|
@ -100,7 +100,7 @@ void CThread::sleep(unsigned int ms)
|
|||
ts.tv_sec = ms / 1000U;
|
||||
ts.tv_nsec = (ms % 1000U) * 1000000U;
|
||||
|
||||
::nanosleep(&ts, NULL);
|
||||
::nanosleep(&ts, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2006-2016,2020,2024,2025 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,29 +34,27 @@
|
|||
#endif
|
||||
|
||||
CUDPSocket::CUDPSocket(const std::string& address, unsigned short port) :
|
||||
m_address_save(address),
|
||||
m_port_save(port),
|
||||
m_counter(0U)
|
||||
m_localAddress(address),
|
||||
m_localPort(port),
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
m_fd(INVALID_SOCKET),
|
||||
#else
|
||||
m_fd(-1),
|
||||
#endif
|
||||
m_af(AF_UNSPEC)
|
||||
{
|
||||
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 short port) :
|
||||
m_address_save(),
|
||||
m_port_save(port),
|
||||
m_counter(0U)
|
||||
m_localAddress(),
|
||||
m_localPort(port),
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
m_fd(INVALID_SOCKET),
|
||||
#else
|
||||
m_fd(-1),
|
||||
#endif
|
||||
m_af(AF_UNSPEC)
|
||||
{
|
||||
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()
|
||||
|
|
@ -93,10 +91,10 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
|
|||
std::string portstr = std::to_string(port);
|
||||
struct addrinfo *res;
|
||||
|
||||
/* port is always digits, no needs to lookup service */
|
||||
/* 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);
|
||||
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));
|
||||
|
|
@ -107,9 +105,11 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
|
|||
return err;
|
||||
}
|
||||
|
||||
::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen);
|
||||
address_length = (unsigned int)res->ai_addrlen;
|
||||
|
||||
freeaddrinfo(res);
|
||||
::memcpy(&addr, res->ai_addr, address_length);
|
||||
|
||||
::freeaddrinfo(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -119,35 +119,35 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
|
|||
if (addr1.ss_family != addr2.ss_family)
|
||||
return false;
|
||||
|
||||
if (type == IMT_ADDRESS_AND_PORT) {
|
||||
if (type == IPMATCHTYPE::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;
|
||||
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) {
|
||||
} else if (type == IPMATCHTYPE::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;
|
||||
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;
|
||||
|
|
@ -163,35 +163,38 @@ bool CUDPSocket::isNone(const sockaddr_storage& addr)
|
|||
|
||||
bool CUDPSocket::open(const sockaddr_storage& address)
|
||||
{
|
||||
return open(address.ss_family);
|
||||
m_af = address.ss_family;
|
||||
|
||||
return open();
|
||||
}
|
||||
|
||||
bool CUDPSocket::open(unsigned int af)
|
||||
bool CUDPSocket::open()
|
||||
{
|
||||
return open(0, af, m_address_save, m_port_save);
|
||||
}
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
assert(m_fd == INVALID_SOCKET);
|
||||
#else
|
||||
assert(m_fd == -1);
|
||||
#endif
|
||||
|
||||
bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port)
|
||||
{
|
||||
sockaddr_storage addr;
|
||||
unsigned int addrlen;
|
||||
struct addrinfo hints;
|
||||
|
||||
::memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = af;
|
||||
hints.ai_family = m_af;
|
||||
|
||||
/* to determine protocol family, call lookup() first. */
|
||||
int err = lookup(address, port, addr, addrlen, hints);
|
||||
// To determine protocol family, call lookup() on the local address first.
|
||||
int err = lookup(m_localAddress, m_localPort, addr, addrlen, hints);
|
||||
if (err != 0) {
|
||||
LogError("The local address is invalid - %s", address.c_str());
|
||||
LogError("The local address is invalid - %s", m_localAddress.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
close(index);
|
||||
m_af = addr.ss_family;
|
||||
|
||||
int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
m_fd = ::socket(m_af, SOCK_DGRAM, 0);
|
||||
if (m_fd < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Cannot create the UDP socket, err: %lu", ::GetLastError());
|
||||
#else
|
||||
|
|
@ -200,62 +203,58 @@ bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std
|
|||
return false;
|
||||
}
|
||||
|
||||
m_address[index] = address;
|
||||
m_port[index] = port;
|
||||
m_af[index] = addr.ss_family;
|
||||
m_fd[index] = fd;
|
||||
|
||||
if (port > 0U) {
|
||||
if (m_localPort > 0U) {
|
||||
int reuse = 1;
|
||||
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
|
||||
if (::setsockopt(m_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
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) {
|
||||
if (::bind(m_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
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo("Opening UDP port on %hu", port);
|
||||
LogInfo("Opening UDP port on %hu", m_localPort);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length)
|
||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
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)
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (m_fd == INVALID_SOCKET)
|
||||
return 0;
|
||||
#else
|
||||
if (m_fd == -1)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
// Check that the readfrom() won't block
|
||||
struct pollfd pfd;
|
||||
pfd.fd = m_fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
|
||||
// Return immediately
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int ret = WSAPoll(pfd, n, 0);
|
||||
int ret = WSAPoll(&pfd, 1, 0);
|
||||
#else
|
||||
int ret = ::poll(pfd, n, 0);
|
||||
int ret = ::poll(&pfd, 1, 0);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -266,14 +265,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
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)
|
||||
if ((pfd.revents & POLLIN) == 0)
|
||||
return 0;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -283,9 +275,9 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
#else
|
||||
ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -294,7 +286,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
LogError("Error returned from recvfrom, err: %d", errno);
|
||||
|
||||
if (len == -1 && errno == ENOTSOCK) {
|
||||
LogMessage("Re-opening UDP port on %hu", m_port[index]);
|
||||
LogMessage("Re-opening UDP port on %hu", m_localPort);
|
||||
close();
|
||||
open();
|
||||
}
|
||||
|
|
@ -302,43 +294,43 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
return -1;
|
||||
}
|
||||
|
||||
m_counter++;
|
||||
address_length = size;
|
||||
addressLength = size;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length)
|
||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
assert(length > 0U);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
assert(m_fd != INVALID_SOCKET);
|
||||
#else
|
||||
assert(m_fd >= 0);
|
||||
#endif
|
||||
|
||||
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);
|
||||
int ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
|
||||
#else
|
||||
ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
|
||||
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Error returned from sendto, err: %lu", ::GetLastError());
|
||||
LogError("Error returned from sendto, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Error returned from sendto, err: %d", errno);
|
||||
LogError("Error returned from sendto, err: %d", errno);
|
||||
#endif
|
||||
} else {
|
||||
} else {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (ret == int(length))
|
||||
result = true;
|
||||
if (ret == int(length))
|
||||
result = true;
|
||||
#else
|
||||
if (ret == ssize_t(length))
|
||||
result = true;
|
||||
if (ret == ssize_t(length))
|
||||
result = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -346,18 +338,16 @@ bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const s
|
|||
|
||||
void CUDPSocket::close()
|
||||
{
|
||||
for (unsigned int i = 0; i < UDP_SOCKET_MAX; i++)
|
||||
close(i);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (m_fd != INVALID_SOCKET) {
|
||||
::closesocket(m_fd);
|
||||
m_fd = INVALID_SOCKET;
|
||||
}
|
||||
#else
|
||||
if (m_fd >= 0) {
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2011,2013,2015,2016,2020,2024,2025 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,13 +35,9 @@
|
|||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#if !defined(UDP_SOCKET_MAX)
|
||||
#define UDP_SOCKET_MAX 1
|
||||
#endif
|
||||
|
||||
enum IPMATCHTYPE {
|
||||
IMT_ADDRESS_AND_PORT,
|
||||
IMT_ADDRESS_ONLY
|
||||
enum class IPMATCHTYPE {
|
||||
ADDRESS_AND_PORT,
|
||||
ADDRESS_ONLY
|
||||
};
|
||||
|
||||
class CUDPSocket {
|
||||
|
|
@ -50,34 +46,34 @@ public:
|
|||
CUDPSocket(unsigned short port = 0U);
|
||||
~CUDPSocket();
|
||||
|
||||
bool open(unsigned int af = AF_UNSPEC);
|
||||
bool open();
|
||||
bool open(const sockaddr_storage& address);
|
||||
bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short 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);
|
||||
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength);
|
||||
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength);
|
||||
|
||||
void close();
|
||||
void close(const unsigned int index);
|
||||
|
||||
static void startup();
|
||||
static void shutdown();
|
||||
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength, struct addrinfo& hints);
|
||||
|
||||
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
|
||||
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IPMATCHTYPE::ADDRESS_AND_PORT);
|
||||
|
||||
static bool isNone(const sockaddr_storage& addr);
|
||||
|
||||
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;
|
||||
std::string m_localAddress;
|
||||
unsigned short m_localPort;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SOCKET m_fd;
|
||||
int m_af;
|
||||
#else
|
||||
int m_fd;
|
||||
sa_family_t m_af;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009,2014,2015,2016 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2009,2014,2015,2016,2025 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
|
||||
|
|
@ -19,14 +19,14 @@
|
|||
|
||||
void CUtils::dump(const std::string& title, const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
dump(2U, title, data, length);
|
||||
}
|
||||
|
||||
void CUtils::dump(int level, const std::string& title, const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
::Log(level, "%s", title.c_str());
|
||||
|
||||
|
|
@ -72,14 +72,14 @@ void CUtils::dump(int level, const std::string& title, const unsigned char* data
|
|||
|
||||
void CUtils::dump(const std::string& title, const bool* bits, unsigned int length)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
dump(2U, title, bits, length);
|
||||
}
|
||||
|
||||
void CUtils::dump(int level, const std::string& title, const bool* bits, unsigned int length)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
unsigned char bytes[100U];
|
||||
unsigned int nBytes = 0U;
|
||||
|
|
@ -91,7 +91,7 @@ void CUtils::dump(int level, const std::string& title, const bool* bits, unsigne
|
|||
|
||||
void CUtils::byteToBitsBE(unsigned char byte, bool* bits)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
bits[0U] = (byte & 0x80U) == 0x80U;
|
||||
bits[1U] = (byte & 0x40U) == 0x40U;
|
||||
|
|
@ -105,7 +105,7 @@ void CUtils::byteToBitsBE(unsigned char byte, bool* bits)
|
|||
|
||||
void CUtils::byteToBitsLE(unsigned char byte, bool* bits)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
bits[0U] = (byte & 0x01U) == 0x01U;
|
||||
bits[1U] = (byte & 0x02U) == 0x02U;
|
||||
|
|
@ -119,7 +119,7 @@ void CUtils::byteToBitsLE(unsigned char byte, bool* bits)
|
|||
|
||||
void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
byte = bits[0U] ? 0x80U : 0x00U;
|
||||
byte |= bits[1U] ? 0x40U : 0x00U;
|
||||
|
|
@ -133,7 +133,7 @@ void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
|
|||
|
||||
void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
assert(bits != nullptr);
|
||||
|
||||
byte = bits[0U] ? 0x01U : 0x00U;
|
||||
byte |= bits[1U] ? 0x02U : 0x00U;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2021,2023,2024,2025 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
|
||||
|
|
@ -19,6 +19,6 @@
|
|||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
const char* VERSION = "20230212";
|
||||
const char* VERSION = "20250615";
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2018,2019,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2018,2019,2020,2025 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
|
||||
|
|
@ -27,8 +27,9 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
|
||||
const unsigned char DX_REQ[] = {0x5DU, 0x71U, 0x5FU};
|
||||
const unsigned char DX_REQ[] = {0x5DU, 0x71U, 0x5FU}; // Followed by 2B (FT-70D) 29 (FTM-100D) 28 (FT2D)
|
||||
const unsigned char CONN_REQ[] = {0x5DU, 0x23U, 0x5FU};
|
||||
const unsigned char DISC_REQ[] = {0x5DU, 0x2AU, 0x5FU};
|
||||
const unsigned char ALL_REQ[] = {0x5DU, 0x66U, 0x5FU};
|
||||
|
|
@ -48,26 +49,26 @@ m_callsign(callsign),
|
|||
m_node(),
|
||||
m_network(network),
|
||||
m_reflectors(reflectors),
|
||||
m_reflector(NULL),
|
||||
m_reflector(nullptr),
|
||||
m_id(),
|
||||
m_name(),
|
||||
m_command(NULL),
|
||||
m_command(nullptr),
|
||||
m_txFrequency(0U),
|
||||
m_rxFrequency(0U),
|
||||
m_timer(1000U, 1U),
|
||||
m_seqNo(0U),
|
||||
m_header(NULL),
|
||||
m_csd1(NULL),
|
||||
m_csd2(NULL),
|
||||
m_csd3(NULL),
|
||||
m_status(WXSI_NONE),
|
||||
m_header(nullptr),
|
||||
m_csd1(nullptr),
|
||||
m_csd2(nullptr),
|
||||
m_csd3(nullptr),
|
||||
m_status(WXSI_STATUS::NONE),
|
||||
m_start(0U),
|
||||
m_search(),
|
||||
m_busy(false),
|
||||
m_busyTimer(3000U, 1U),
|
||||
m_bufferTX(10000U, "YSF Wires-X TX Buffer")
|
||||
{
|
||||
assert(network != NULL);
|
||||
assert(network != nullptr);
|
||||
|
||||
m_node = callsign;
|
||||
if (suffix.size() > 0U) {
|
||||
|
|
@ -187,35 +188,35 @@ bool CWiresX::start()
|
|||
|
||||
WX_STATUS CWiresX::process(const unsigned char* data, const unsigned char* source, const CYSFFICH& fich, bool wiresXCommandPassthrough)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(source != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(source != nullptr);
|
||||
|
||||
unsigned char dt = fich.getDT();
|
||||
if (dt != YSF_DT_DATA_FR_MODE)
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
|
||||
unsigned char fi = fich.getFI();
|
||||
if (fi != YSF_FI_COMMUNICATIONS)
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
|
||||
CYSFPayload payload;
|
||||
|
||||
unsigned char fn = fich.getFN();
|
||||
if (fn == 0U)
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
|
||||
if (fn == 1U) {
|
||||
bool valid = payload.readDataFRModeData2(data, m_command + 0U);
|
||||
if (!valid)
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
} else {
|
||||
bool valid = payload.readDataFRModeData1(data, m_command + (fn - 2U) * 40U + 20U);
|
||||
if (!valid)
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
|
||||
valid = payload.readDataFRModeData2(data, m_command + (fn - 2U) * 40U + 40U);
|
||||
if (!valid)
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
unsigned char ft = fich.getFT();
|
||||
|
|
@ -234,52 +235,52 @@ WX_STATUS CWiresX::process(const unsigned char* data, const unsigned char* sourc
|
|||
}
|
||||
|
||||
if (!valid)
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
|
||||
CUtils::dump(1U, "Received Wires-X command", m_command, cmd_len);
|
||||
|
||||
// If we are using WiresX Passthrough (we already know we are on a YSF2xxx room from YSFGateway
|
||||
// YSFGateway.cpp is telling us to pass the command to the network, so do not process locally unless it's a disconnect
|
||||
if (wiresXCommandPassthrough) {
|
||||
if (::memcmp(m_command + 1U, DX_REQ, 3U) == 0) {
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
} else if (::memcmp(m_command + 1U, ALL_REQ, 3U) == 0) {
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
} else if (::memcmp(m_command + 1U, CONN_REQ, 3U) == 0) {
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
} else if (::memcmp(m_command + 1U, DISC_REQ, 3U) == 0) {
|
||||
processDisconnect(source);
|
||||
return WXS_DISCONNECT;
|
||||
return WX_STATUS::DISCONNECT;
|
||||
} else if (::memcmp(m_command + 1U, CAT_REQ, 3U) == 0) {
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
} else {
|
||||
CUtils::dump("Unknown Wires-X command", m_command, cmd_len);
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
}
|
||||
// Origional Code Here
|
||||
else {
|
||||
if (::memcmp(m_command + 1U, DX_REQ, 3U) == 0) {
|
||||
processDX(source);
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::RECONNECT_CURRENT;
|
||||
} else if (::memcmp(m_command + 1U, ALL_REQ, 3U) == 0) {
|
||||
processAll(source, m_command + 5U);
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
} else if (::memcmp(m_command + 1U, CONN_REQ, 3U) == 0) {
|
||||
return processConnect(source, m_command + 5U);
|
||||
} else if (::memcmp(m_command + 1U, DISC_REQ, 3U) == 0) {
|
||||
processDisconnect(source);
|
||||
return WXS_DISCONNECT;
|
||||
return WX_STATUS::DISCONNECT;
|
||||
} else if (::memcmp(m_command + 1U, CAT_REQ, 3U) == 0) {
|
||||
processCategory(source, m_command + 5U);
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
} else {
|
||||
CUtils::dump("Unknown Wires-X command", m_command, cmd_len);
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
CYSFReflector* CWiresX::getReflector() const
|
||||
|
|
@ -296,7 +297,7 @@ void CWiresX::processDX(const unsigned char* source)
|
|||
{
|
||||
::LogDebug("Received DX from %10.10s", source);
|
||||
|
||||
m_status = WXSI_DX;
|
||||
m_status = WXSI_STATUS::DX;
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +330,7 @@ void CWiresX::processCategory(const unsigned char* source, const unsigned char*
|
|||
m_category.push_back(refl);
|
||||
}
|
||||
|
||||
m_status = WXSI_CATEGORY;
|
||||
m_status = WXSI_STATUS::CATEGORY;
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
|
|
@ -346,7 +347,7 @@ void CWiresX::processAll(const unsigned char* source, const unsigned char* data)
|
|||
if (m_start > 0U)
|
||||
m_start--;
|
||||
|
||||
m_status = WXSI_ALL;
|
||||
m_status = WXSI_STATUS::ALL;
|
||||
|
||||
m_timer.start();
|
||||
} else if (data[0U] == '1' && data[1U] == '1') {
|
||||
|
|
@ -358,7 +359,7 @@ void CWiresX::processAll(const unsigned char* source, const unsigned char* data)
|
|||
|
||||
m_search = std::string((char*)(data + 5U), 16U);
|
||||
|
||||
m_status = WXSI_SEARCH;
|
||||
m_status = WXSI_STATUS::SEARCH;
|
||||
|
||||
m_timer.start();
|
||||
}
|
||||
|
|
@ -374,19 +375,24 @@ WX_STATUS CWiresX::processConnect(const unsigned char* source, const unsigned ch
|
|||
std::string id = std::string((char*)data, 5U);
|
||||
|
||||
m_reflector = m_reflectors.findById(id);
|
||||
if (m_reflector == NULL)
|
||||
return WXS_NONE;
|
||||
if (m_reflector == nullptr) {
|
||||
if(source != nullptr)
|
||||
processDisconnect(source);
|
||||
sendConnectFailedReply();
|
||||
// Keep state on Radio matched with YSFGateway
|
||||
return WX_STATUS::DISCONNECT;
|
||||
}
|
||||
|
||||
m_status = WXSI_CONNECT;
|
||||
m_status = WXSI_STATUS::CONNECT;
|
||||
m_timer.start();
|
||||
|
||||
switch (m_reflector->m_type) {
|
||||
case YT_YSF:
|
||||
return WXS_CONNECT_YSF;
|
||||
case YT_FCS:
|
||||
return WXS_CONNECT_FCS;
|
||||
case YSF_TYPE::YSF:
|
||||
return WX_STATUS::CONNECT_YSF;
|
||||
case YSF_TYPE::FCS:
|
||||
return WX_STATUS::CONNECT_FCS;
|
||||
default:
|
||||
return WXS_NONE;
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,18 +403,18 @@ void CWiresX::processConnect(CYSFReflector* reflector)
|
|||
|
||||
m_reflector = reflector;
|
||||
|
||||
m_status = WXSI_CONNECT;
|
||||
m_status = WXSI_STATUS::CONNECT;
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
void CWiresX::processDisconnect(const unsigned char* source)
|
||||
{
|
||||
if (source != NULL)
|
||||
if (source != nullptr)
|
||||
::LogDebug("Received Disconect from %10.10s", source);
|
||||
|
||||
m_reflector = NULL;
|
||||
m_reflector = nullptr;
|
||||
|
||||
m_status = WXSI_DISCONNECT;
|
||||
m_status = WXSI_STATUS::DISCONNECT;
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
|
|
@ -421,29 +427,29 @@ void CWiresX::clock(unsigned int ms)
|
|||
m_timer.clock(ms);
|
||||
if (m_timer.isRunning() && m_timer.hasExpired()) {
|
||||
switch (m_status) {
|
||||
case WXSI_DX:
|
||||
case WXSI_STATUS::DX:
|
||||
sendDXReply();
|
||||
break;
|
||||
case WXSI_ALL:
|
||||
case WXSI_STATUS::ALL:
|
||||
sendAllReply();
|
||||
break;
|
||||
case WXSI_SEARCH:
|
||||
case WXSI_STATUS::SEARCH:
|
||||
sendSearchReply();
|
||||
break;
|
||||
case WXSI_CONNECT:
|
||||
case WXSI_STATUS::CONNECT:
|
||||
sendConnectReply();
|
||||
break;
|
||||
case WXSI_DISCONNECT:
|
||||
case WXSI_STATUS::DISCONNECT:
|
||||
sendDisconnectReply();
|
||||
break;
|
||||
case WXSI_CATEGORY:
|
||||
case WXSI_STATUS::CATEGORY:
|
||||
sendCategoryReply();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_status = WXSI_NONE;
|
||||
m_status = WXSI_STATUS::NONE;
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
|
|
@ -468,14 +474,14 @@ void CWiresX::clock(unsigned int ms)
|
|||
|
||||
void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNetwork* network)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(length > 0U);
|
||||
|
||||
bool isYSF2XX = true;
|
||||
bool sendWiresXtoNetwork = true;
|
||||
|
||||
// If we don't explicitly pass a network, use the default one.
|
||||
if (network == NULL) {
|
||||
isYSF2XX = false;
|
||||
if (network == nullptr) {
|
||||
sendWiresXtoNetwork = false;
|
||||
network = m_network;
|
||||
}
|
||||
|
||||
|
|
@ -520,7 +526,7 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNe
|
|||
buffer[34U] = seqNo;
|
||||
seqNo += 2U;
|
||||
|
||||
writeData(buffer, network, isYSF2XX);
|
||||
writeData(buffer, network, sendWiresXtoNetwork);
|
||||
|
||||
fich.setFI(YSF_FI_COMMUNICATIONS);
|
||||
|
||||
|
|
@ -567,7 +573,7 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNe
|
|||
buffer[34U] = seqNo;
|
||||
seqNo += 2U;
|
||||
|
||||
writeData(buffer, network, isYSF2XX);
|
||||
writeData(buffer, network, sendWiresXtoNetwork);
|
||||
|
||||
fn++;
|
||||
if (fn >= 8U) {
|
||||
|
|
@ -587,13 +593,13 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNe
|
|||
|
||||
buffer[34U] = seqNo | 0x01U;
|
||||
|
||||
writeData(buffer, network, isYSF2XX);
|
||||
writeData(buffer, network, sendWiresXtoNetwork);
|
||||
}
|
||||
|
||||
void CWiresX::writeData(const unsigned char* buffer, CYSFNetwork* network, bool isYSF2XX)
|
||||
void CWiresX::writeData(const unsigned char* buffer, CYSFNetwork* network, bool sendWiresXtoNetwork)
|
||||
{
|
||||
if (isYSF2XX) {
|
||||
// Send YSF2XXX Wires-X reply directly to the network
|
||||
if (sendWiresXtoNetwork) {
|
||||
// Send WiresX directly to the network
|
||||
network->write(buffer);
|
||||
} else {
|
||||
// Send host Wires-X reply using ring buffer
|
||||
|
|
@ -642,22 +648,22 @@ void CWiresX::sendDXReply()
|
|||
for (unsigned int i = 0U; i < 14U; i++)
|
||||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
if (m_reflector == NULL) {
|
||||
data[34U] = '1';
|
||||
data[35U] = '2';
|
||||
if (m_reflector == nullptr) {
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '2'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
data[59U] = '0';
|
||||
} else {
|
||||
data[34U] = '1';
|
||||
data[35U] = '5';
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '3'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
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++)
|
||||
data[i + 41U] = m_reflector->m_name.at(i);
|
||||
data[i + 41U] = std::toupper(m_reflector->m_name.at(i));
|
||||
|
||||
for (unsigned int i = 0U; i < 3U; i++)
|
||||
data[i + 57U] = m_reflector->m_count.at(i);
|
||||
|
|
@ -718,7 +724,7 @@ void CWiresX::sendConnect(CYSFNetwork* network)
|
|||
|
||||
void CWiresX::sendConnectReply()
|
||||
{
|
||||
assert(m_reflector != NULL);
|
||||
assert(m_reflector != nullptr);
|
||||
|
||||
unsigned char data[110U];
|
||||
::memset(data, 0x00U, 110U);
|
||||
|
|
@ -738,14 +744,14 @@ void CWiresX::sendConnectReply()
|
|||
for (unsigned int i = 0U; i < 14U; i++)
|
||||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
data[34U] = '1';
|
||||
data[35U] = '5';
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '3'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
data[i + 36U] = m_reflector->m_id.at(i);
|
||||
data[i + 36U] = m_reflector->m_id.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 16U; i++)
|
||||
data[i + 41U] = m_reflector->m_name.at(i);
|
||||
data[i + 41U] = std::toupper(m_reflector->m_name.at(i));
|
||||
|
||||
for (unsigned int i = 0U; i < 3U; i++)
|
||||
data[i + 57U] = m_reflector->m_count.at(i);
|
||||
|
|
@ -769,6 +775,43 @@ void CWiresX::sendConnectReply()
|
|||
m_seqNo++;
|
||||
}
|
||||
|
||||
void CWiresX::sendConnectFailedReply()
|
||||
{
|
||||
unsigned char data[110U];
|
||||
::memset(data, 0x00U, 110U);
|
||||
::memset(data, ' ', 90U);
|
||||
|
||||
data[0U] = m_seqNo;
|
||||
|
||||
for (unsigned int i = 0U; i < 4U; i++)
|
||||
data[i + 1U] = CONN_RESP[i];
|
||||
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
data[i + 5U] = m_id.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 10U; i++)
|
||||
data[i + 10U] = m_node.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 14U; i++)
|
||||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '0'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
data[59U] = '0';
|
||||
|
||||
data[89U] = 0x03U; // End of data marker
|
||||
data[90U] = CCRC::addCRC(data, 90U);
|
||||
|
||||
CUtils::dump(1U, "Connect Failed Reply", data, 91U);
|
||||
|
||||
createReply(data, 91U);
|
||||
|
||||
m_seqNo++;
|
||||
}
|
||||
|
||||
void CWiresX::sendDisconnectReply()
|
||||
{
|
||||
unsigned char data[110U];
|
||||
|
|
@ -789,8 +832,8 @@ void CWiresX::sendDisconnectReply()
|
|||
for (unsigned int i = 0U; i < 14U; i++)
|
||||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
data[34U] = '1';
|
||||
data[35U] = '2';
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '2'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
|
|
@ -830,13 +873,13 @@ void CWiresX::sendAllReply()
|
|||
for (unsigned int i = 0U; i < 10U; i++)
|
||||
data[i + 12U] = m_node.at(i);
|
||||
|
||||
unsigned int total = curr.size();
|
||||
unsigned int total = (unsigned int)curr.size();
|
||||
if (total > 999U) total = 999U;
|
||||
|
||||
unsigned int n = curr.size() - m_start;
|
||||
unsigned int n = (unsigned int)curr.size() - m_start;
|
||||
if (n > 20U) n = 20U;
|
||||
|
||||
::sprintf((char*)(data + 22U), "%03u%03u", n, total);
|
||||
::sprintf((char*)(data + 22U), "%03u%03u", 20U, total);
|
||||
|
||||
data[28U] = 0x0DU;
|
||||
|
||||
|
|
@ -852,7 +895,7 @@ void CWiresX::sendAllReply()
|
|||
data[i + offset + 1U] = refl->m_id.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 16U; i++)
|
||||
data[i + offset + 6U] = refl->m_name.at(i);
|
||||
data[i + offset + 6U] = std::toupper(refl->m_name.at(i));
|
||||
|
||||
for (unsigned int i = 0U; i < 3U; i++)
|
||||
data[i + offset + 22U] = refl->m_count.at(i);
|
||||
|
|
@ -868,7 +911,16 @@ void CWiresX::sendAllReply()
|
|||
|
||||
unsigned int k = 1029U - offset;
|
||||
for(unsigned int i = 0U; i < k; i++)
|
||||
data[i + offset] = 0x20U;
|
||||
{
|
||||
if (i % 50U == 49 && i>0)
|
||||
{
|
||||
data[i + offset] = 0x0DU;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[i + offset] = 0x20U;
|
||||
}
|
||||
}
|
||||
|
||||
offset += k;
|
||||
|
||||
|
|
@ -914,13 +966,13 @@ void CWiresX::sendSearchReply()
|
|||
|
||||
data[22U] = '1';
|
||||
|
||||
unsigned int total = search.size();
|
||||
unsigned int total = (unsigned int)search.size();
|
||||
if (total > 999U) total = 999U;
|
||||
|
||||
unsigned int n = search.size() - m_start;
|
||||
unsigned int n = (unsigned int)search.size() - m_start;
|
||||
if (n > 20U) n = 20U;
|
||||
|
||||
::sprintf((char*)(data + 23U), "%02u%03u", n, total);
|
||||
::sprintf((char*)(data + 23U), "%02u%03u", 20U, total);
|
||||
|
||||
data[28U] = 0x0DU;
|
||||
|
||||
|
|
@ -936,7 +988,7 @@ void CWiresX::sendSearchReply()
|
|||
data[i + offset + 1U] = refl->m_id.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 16U; i++)
|
||||
data[i + offset + 6U] = refl->m_name.at(i);
|
||||
data[i + offset + 6U] = std::toupper(refl->m_name.at(i));
|
||||
|
||||
for (unsigned int i = 0U; i < 3U; i++)
|
||||
data[i + offset + 22U] = refl->m_count.at(i);
|
||||
|
|
@ -951,8 +1003,12 @@ void CWiresX::sendSearchReply()
|
|||
}
|
||||
|
||||
unsigned int k = 1029U - offset;
|
||||
for(unsigned int i = 0U; i < k; i++)
|
||||
data[i + offset] = 0x20U;
|
||||
for (unsigned int i = 0U; i < k; i++) {
|
||||
if (((i % 50U) == 49U) && (i > 0U))
|
||||
data[i + offset] = 0x0DU;
|
||||
else
|
||||
data[i + offset] = 0x20U;
|
||||
}
|
||||
|
||||
offset += k;
|
||||
|
||||
|
|
@ -1023,11 +1079,11 @@ void CWiresX::sendCategoryReply()
|
|||
for (unsigned int i = 0U; i < 10U; i++)
|
||||
data[i + 12U] = m_node.at(i);
|
||||
|
||||
unsigned int n = m_category.size();
|
||||
unsigned int n = (unsigned int)m_category.size();
|
||||
if (n > 20U)
|
||||
n = 20U;
|
||||
|
||||
::sprintf((char*)(data + 22U), "%03u%03u", n, n);
|
||||
::sprintf((char*)(data + 22U), "%03u%03u", 20U, n);
|
||||
|
||||
data[28U] = 0x0DU;
|
||||
|
||||
|
|
@ -1043,7 +1099,7 @@ void CWiresX::sendCategoryReply()
|
|||
data[i + offset + 1U] = refl->m_id.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 16U; i++)
|
||||
data[i + offset + 6U] = refl->m_name.at(i);
|
||||
data[i + offset + 6U] = std::toupper(refl->m_name.at(i));
|
||||
|
||||
for (unsigned int i = 0U; i < 3U; i++)
|
||||
data[i + offset + 22U] = refl->m_count.at(i);
|
||||
|
|
@ -1058,8 +1114,12 @@ void CWiresX::sendCategoryReply()
|
|||
}
|
||||
|
||||
unsigned int k = 1029U - offset;
|
||||
for(unsigned int i = 0U; i < k; i++)
|
||||
data[i + offset] = 0x20U;
|
||||
for (unsigned int i = 0U; i < k; i++) {
|
||||
if (((i % 50U) == 49U) && (i > 0U))
|
||||
data[i + offset] = 0x0DU;
|
||||
else
|
||||
data[i + offset] = 0x20U;
|
||||
}
|
||||
|
||||
offset += k;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2018,2019,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2018,2019,2020,2025 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,21 +28,22 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
enum WX_STATUS {
|
||||
WXS_NONE,
|
||||
WXS_CONNECT_YSF,
|
||||
WXS_CONNECT_FCS,
|
||||
WXS_DISCONNECT
|
||||
enum class WX_STATUS {
|
||||
NONE,
|
||||
CONNECT_YSF,
|
||||
CONNECT_FCS,
|
||||
DISCONNECT,
|
||||
RECONNECT_CURRENT
|
||||
};
|
||||
|
||||
enum WXSI_STATUS {
|
||||
WXSI_NONE,
|
||||
WXSI_DX,
|
||||
WXSI_CONNECT,
|
||||
WXSI_DISCONNECT,
|
||||
WXSI_ALL,
|
||||
WXSI_SEARCH,
|
||||
WXSI_CATEGORY
|
||||
enum class WXSI_STATUS {
|
||||
NONE,
|
||||
DX,
|
||||
CONNECT,
|
||||
DISCONNECT,
|
||||
ALL,
|
||||
SEARCH,
|
||||
CATEGORY
|
||||
};
|
||||
|
||||
class CWiresX {
|
||||
|
|
@ -66,7 +67,7 @@ public:
|
|||
void setReflector(CYSFReflector* reflector);
|
||||
|
||||
void processConnect(CYSFReflector* reflector);
|
||||
void processDisconnect(const unsigned char* source = NULL);
|
||||
void processDisconnect(const unsigned char* source = nullptr);
|
||||
|
||||
void sendConnect(CYSFNetwork* network);
|
||||
|
||||
|
|
@ -105,14 +106,15 @@ private:
|
|||
|
||||
void sendDXReply();
|
||||
void sendConnectReply();
|
||||
void sendConnectFailedReply();
|
||||
void sendDisconnectReply();
|
||||
void sendAllReply();
|
||||
void sendSearchReply();
|
||||
void sendSearchNotFoundReply();
|
||||
void sendCategoryReply();
|
||||
|
||||
void createReply(const unsigned char* data, unsigned int length, CYSFNetwork* network = NULL);
|
||||
void writeData(const unsigned char* data, CYSFNetwork* network, bool isYSF2XX);
|
||||
void createReply(const unsigned char* data, unsigned int length, CYSFNetwork* network = nullptr);
|
||||
void writeData(const unsigned char* data, CYSFNetwork* network, bool sendWiresXtoNetwork);
|
||||
unsigned char calculateFT(unsigned int length, unsigned int offset) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2016,2025 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
|
||||
|
|
@ -36,12 +36,12 @@ const uint32_t M = 2U;
|
|||
const unsigned int K = 5U;
|
||||
|
||||
CYSFConvolution::CYSFConvolution() :
|
||||
m_metrics1(NULL),
|
||||
m_metrics2(NULL),
|
||||
m_oldMetrics(NULL),
|
||||
m_newMetrics(NULL),
|
||||
m_decisions(NULL),
|
||||
m_dp(NULL)
|
||||
m_metrics1(nullptr),
|
||||
m_metrics2(nullptr),
|
||||
m_oldMetrics(nullptr),
|
||||
m_newMetrics(nullptr),
|
||||
m_decisions(nullptr),
|
||||
m_dp(nullptr)
|
||||
{
|
||||
m_metrics1 = new uint16_t[16U];
|
||||
m_metrics2 = new uint16_t[16U];
|
||||
|
|
@ -98,7 +98,7 @@ void CYSFConvolution::decode(uint8_t s0, uint8_t s1)
|
|||
|
||||
void CYSFConvolution::chainback(unsigned char* out, unsigned int nBits)
|
||||
{
|
||||
assert(out != NULL);
|
||||
assert(out != nullptr);
|
||||
|
||||
uint32_t state = 0U;
|
||||
|
||||
|
|
@ -115,8 +115,8 @@ void CYSFConvolution::chainback(unsigned char* out, unsigned int nBits)
|
|||
|
||||
void CYSFConvolution::encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(out != NULL);
|
||||
assert(in != nullptr);
|
||||
assert(out != nullptr);
|
||||
assert(nBits > 0U);
|
||||
|
||||
uint8_t d1 = 0U, d2 = 0U, d3 = 0U, d4 = 0U;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2019,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2019,2020,2025 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,7 +55,7 @@ const unsigned int INTERLEAVE_TABLE[] = {
|
|||
38U, 78U, 118U, 158U, 198U };
|
||||
|
||||
CYSFFICH::CYSFFICH(const CYSFFICH& fich) :
|
||||
m_fich(NULL)
|
||||
m_fich(nullptr)
|
||||
{
|
||||
m_fich = new unsigned char[6U];
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ m_fich(NULL)
|
|||
}
|
||||
|
||||
CYSFFICH::CYSFFICH() :
|
||||
m_fich(NULL)
|
||||
m_fich(nullptr)
|
||||
{
|
||||
m_fich = new unsigned char[6U];
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ CYSFFICH::~CYSFFICH()
|
|||
|
||||
bool CYSFFICH::decode(const unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
assert(bytes != nullptr);
|
||||
|
||||
// Skip the sync bytes
|
||||
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||
|
|
@ -116,7 +116,7 @@ bool CYSFFICH::decode(const unsigned char* bytes)
|
|||
|
||||
void CYSFFICH::encode(unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
assert(bytes != nullptr);
|
||||
|
||||
// Skip the sync bytes
|
||||
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016-2020,2024,2025 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
|
||||
|
|
@ -50,6 +50,17 @@ const char* DEFAULT_INI_FILE = "/etc/YSFGateway.ini";
|
|||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
static bool m_killed = false;
|
||||
static int m_signal = 0;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
static void sigHandler(int signum)
|
||||
{
|
||||
m_killed = true;
|
||||
m_signal = signum;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* iniFile = DEFAULT_INI_FILE;
|
||||
|
|
@ -68,11 +79,40 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
CYSFGateway* gateway = new CYSFGateway(std::string(iniFile));
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
::signal(SIGINT, sigHandler);
|
||||
::signal(SIGTERM, sigHandler);
|
||||
::signal(SIGHUP, sigHandler);
|
||||
#endif
|
||||
|
||||
int ret = gateway->run();
|
||||
int ret = 0;
|
||||
|
||||
delete gateway;
|
||||
do {
|
||||
m_signal = 0;
|
||||
m_killed = false;
|
||||
|
||||
CYSFGateway* gateway = new CYSFGateway(std::string(iniFile));
|
||||
ret = gateway->run();
|
||||
|
||||
delete gateway;
|
||||
|
||||
switch (m_signal) {
|
||||
case 0:
|
||||
break;
|
||||
case 2:
|
||||
::LogInfo("YSFGateway-%s exited on receipt of SIGINT", VERSION);
|
||||
break;
|
||||
case 15:
|
||||
::LogInfo("YSFGateway-%s exited on receipt of SIGTERM", VERSION);
|
||||
break;
|
||||
case 1:
|
||||
::LogInfo("YSFGateway-%s is restarting on receipt of SIGHUP", VERSION);
|
||||
break;
|
||||
default:
|
||||
::LogInfo("YSFGateway-%s exited on receipt of an unknown signal", VERSION);
|
||||
break;
|
||||
}
|
||||
} while (m_signal == 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -81,14 +121,14 @@ CYSFGateway::CYSFGateway(const std::string& configFile) :
|
|||
m_callsign(),
|
||||
m_suffix(),
|
||||
m_conf(configFile),
|
||||
m_writer(NULL),
|
||||
m_gps(NULL),
|
||||
m_reflectors(NULL),
|
||||
m_wiresX(NULL),
|
||||
m_writer(nullptr),
|
||||
m_gps(nullptr),
|
||||
m_reflectors(nullptr),
|
||||
m_wiresX(nullptr),
|
||||
m_dtmf(),
|
||||
m_ysfNetwork(NULL),
|
||||
m_fcsNetwork(NULL),
|
||||
m_linkType(LINK_NONE),
|
||||
m_ysfNetwork(nullptr),
|
||||
m_fcsNetwork(nullptr),
|
||||
m_linkType(LINK_TYPE::NONE),
|
||||
m_current(),
|
||||
m_startup(),
|
||||
m_options(),
|
||||
|
|
@ -96,7 +136,7 @@ m_exclude(false),
|
|||
m_inactivityTimer(1000U),
|
||||
m_lostTimer(1000U, 120U),
|
||||
m_fcsNetworkEnabled(false),
|
||||
m_remoteSocket(NULL)
|
||||
m_remoteSocket(nullptr)
|
||||
{
|
||||
CUDPSocket::startup();
|
||||
}
|
||||
|
|
@ -143,7 +183,7 @@ int CYSFGateway::run()
|
|||
// If we are currently root...
|
||||
if (getuid() == 0) {
|
||||
struct passwd* user = ::getpwnam("mmdvm");
|
||||
if (user == NULL) {
|
||||
if (user == nullptr) {
|
||||
::fprintf(stderr, "Could not get the mmdvm user, exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -239,9 +279,8 @@ int CYSFGateway::run()
|
|||
|
||||
std::string fileName = m_conf.getYSFNetworkHosts();
|
||||
unsigned int reloadTime = m_conf.getYSFNetworkReloadTime();
|
||||
bool wiresXMakeUpper = m_conf.getWiresXMakeUpper();
|
||||
|
||||
m_reflectors = new CYSFReflectors(fileName, reloadTime, wiresXMakeUpper);
|
||||
m_reflectors = new CYSFReflectors(fileName, reloadTime);
|
||||
m_reflectors->reload();
|
||||
|
||||
createWiresX(&rptNetwork);
|
||||
|
|
@ -253,13 +292,14 @@ int CYSFGateway::run()
|
|||
ret = m_remoteSocket->open();
|
||||
if (!ret) {
|
||||
delete m_remoteSocket;
|
||||
m_remoteSocket = NULL;
|
||||
m_remoteSocket = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
m_startup = m_conf.getNetworkStartup();
|
||||
m_options = m_conf.getNetworkOptions();
|
||||
bool revert = m_conf.getNetworkRevert();
|
||||
bool reconnect = m_conf.getNetworkReconnect();
|
||||
bool wiresXCommandPassthrough = m_conf.getWiresXCommandPassthrough();
|
||||
|
||||
startupLinking();
|
||||
|
|
@ -270,7 +310,7 @@ int CYSFGateway::run()
|
|||
LogMessage("YSFGateway-%s is starting", VERSION);
|
||||
LogMessage("Built %s %s (GitID #%.7s)", __TIME__, __DATE__, gitversion);
|
||||
|
||||
for (;;) {
|
||||
while (!m_killed) {
|
||||
unsigned char buffer[200U];
|
||||
memset(buffer, 0U, 200U);
|
||||
|
||||
|
|
@ -282,29 +322,29 @@ int CYSFGateway::run()
|
|||
unsigned char dt = fich.getDT();
|
||||
|
||||
CYSFReflector* reflector = m_wiresX->getReflector();
|
||||
if (m_ysfNetwork != NULL && m_linkType == LINK_YSF && wiresXCommandPassthrough && reflector->m_wiresX) {
|
||||
if (m_ysfNetwork != nullptr && m_linkType == LINK_TYPE::YSF && wiresXCommandPassthrough && reflector != nullptr && reflector->m_wiresX) {
|
||||
processDTMF(buffer, dt);
|
||||
processWiresX(buffer, fich, true, wiresXCommandPassthrough);
|
||||
processWiresX(buffer, fich, reflector->m_wiresX, wiresXCommandPassthrough); // Honour reflector->m_wiresX status
|
||||
} else {
|
||||
processDTMF(buffer, dt);
|
||||
processWiresX(buffer, fich, false, wiresXCommandPassthrough);
|
||||
reflector = m_wiresX->getReflector(); //reflector may have changed
|
||||
if (m_ysfNetwork != NULL && m_linkType == LINK_YSF && reflector->m_wiresX)
|
||||
processWiresX(buffer, fich, false, wiresXCommandPassthrough); // Remove the assumption that wiresXCommandPassthrough is set
|
||||
reflector = m_wiresX->getReflector(); // reflector may have changed
|
||||
if (m_ysfNetwork != nullptr && m_linkType == LINK_TYPE::YSF && reflector != nullptr && reflector->m_wiresX)
|
||||
m_exclude = (dt == YSF_DT_DATA_FR_MODE);
|
||||
}
|
||||
|
||||
if (m_gps != NULL)
|
||||
if (m_gps != nullptr)
|
||||
m_gps->data(buffer + 14U, buffer + 35U, fich);
|
||||
}
|
||||
|
||||
if (m_ysfNetwork != NULL && m_linkType == LINK_YSF && !m_exclude) {
|
||||
if (m_ysfNetwork != nullptr && m_linkType == LINK_TYPE::YSF && !m_exclude) {
|
||||
if (::memcmp(buffer + 0U, "YSFD", 4U) == 0) {
|
||||
m_ysfNetwork->write(buffer);
|
||||
m_inactivityTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_fcsNetwork != NULL && m_linkType == LINK_FCS && !m_exclude) {
|
||||
if (m_fcsNetwork != nullptr && m_linkType == LINK_TYPE::FCS && !m_exclude) {
|
||||
if (::memcmp(buffer + 0U, "YSFD", 4U) == 0) {
|
||||
m_fcsNetwork->write(buffer);
|
||||
m_inactivityTimer.start();
|
||||
|
|
@ -312,16 +352,16 @@ int CYSFGateway::run()
|
|||
}
|
||||
|
||||
if ((buffer[34U] & 0x01U) == 0x01U) {
|
||||
if (m_gps != NULL)
|
||||
if (m_gps != nullptr)
|
||||
m_gps->reset();
|
||||
m_dtmf.reset();
|
||||
m_exclude = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ysfNetwork != NULL) {
|
||||
if (m_ysfNetwork != nullptr) {
|
||||
while (m_ysfNetwork->read(buffer) > 0U) {
|
||||
if (m_linkType == LINK_YSF) {
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
// Only pass through YSF data packets
|
||||
if (::memcmp(buffer + 0U, "YSFD", 4U) == 0 && !m_wiresX->isBusy())
|
||||
rptNetwork.write(buffer);
|
||||
|
|
@ -331,9 +371,9 @@ int CYSFGateway::run()
|
|||
}
|
||||
}
|
||||
|
||||
if (m_fcsNetwork != NULL) {
|
||||
if (m_fcsNetwork != nullptr) {
|
||||
while (m_fcsNetwork->read(buffer) > 0U) {
|
||||
if (m_linkType == LINK_FCS) {
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
// Only pass through YSF data packets
|
||||
if (::memcmp(buffer + 0U, "YSFD", 4U) == 0 && !m_wiresX->isBusy())
|
||||
rptNetwork.write(buffer);
|
||||
|
|
@ -343,59 +383,41 @@ int CYSFGateway::run()
|
|||
}
|
||||
}
|
||||
|
||||
if (m_remoteSocket != NULL)
|
||||
if (m_remoteSocket != nullptr)
|
||||
processRemoteCommands();
|
||||
|
||||
unsigned int ms = stopWatch.elapsed();
|
||||
stopWatch.start();
|
||||
|
||||
rptNetwork.clock(ms);
|
||||
if (m_ysfNetwork != NULL)
|
||||
if (m_ysfNetwork != nullptr)
|
||||
m_ysfNetwork->clock(ms);
|
||||
if (m_fcsNetwork != NULL)
|
||||
if (m_fcsNetwork != nullptr)
|
||||
m_fcsNetwork->clock(ms);
|
||||
if (m_writer != NULL)
|
||||
if (m_writer != nullptr)
|
||||
m_writer->clock(ms);
|
||||
m_wiresX->clock(ms);
|
||||
|
||||
m_inactivityTimer.clock(ms);
|
||||
if (m_inactivityTimer.isRunning() && m_inactivityTimer.hasExpired()) {
|
||||
if (revert) {
|
||||
if (m_current != m_startup) {
|
||||
if (m_linkType == LINK_YSF) {
|
||||
m_wiresX->processDisconnect();
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
m_ysfNetwork->clearDestination();
|
||||
}
|
||||
|
||||
if (m_linkType == LINK_FCS) {
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
m_fcsNetwork->clearDestination();
|
||||
}
|
||||
|
||||
m_current.clear();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
|
||||
if (m_linkType != LINK_TYPE::NONE && m_current != m_startup) {
|
||||
LogMessage("Reverting to startup ref due to inactivity");
|
||||
disconnectCurrentReflector();
|
||||
startupLinking();
|
||||
} else if (m_linkType == LINK_TYPE::NONE && reconnect) {
|
||||
// reconnect if current one is timeout and reconnect = 1
|
||||
LogMessage("Reconnecting startup reflector ...");
|
||||
startupLinking();
|
||||
}
|
||||
} else {
|
||||
if (m_linkType == LINK_YSF) {
|
||||
if (m_linkType != LINK_TYPE::NONE && !reconnect) {
|
||||
LogMessage("Disconnecting due to inactivity");
|
||||
m_wiresX->processDisconnect();
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
m_ysfNetwork->clearDestination();
|
||||
disconnectCurrentReflector();
|
||||
} else if (m_linkType == LINK_TYPE::NONE && reconnect) {
|
||||
LogMessage("Reconnecting reflector ...");
|
||||
reconnectReflector(m_current);
|
||||
}
|
||||
|
||||
if (m_linkType == LINK_FCS) {
|
||||
LogMessage("Disconnecting due to inactivity");
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
m_fcsNetwork->clearDestination();
|
||||
}
|
||||
|
||||
m_current.clear();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
}
|
||||
|
||||
m_inactivityTimer.start();
|
||||
|
|
@ -403,21 +425,20 @@ int CYSFGateway::run()
|
|||
|
||||
m_lostTimer.clock(ms);
|
||||
if (m_lostTimer.isRunning() && m_lostTimer.hasExpired()) {
|
||||
if (m_linkType == LINK_YSF) {
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
LogWarning("Link has failed, polls lost");
|
||||
m_wiresX->processDisconnect();
|
||||
m_ysfNetwork->clearDestination();
|
||||
}
|
||||
|
||||
if (m_fcsNetwork != NULL) {
|
||||
if (m_fcsNetwork != nullptr) {
|
||||
LogWarning("Link has failed, polls lost");
|
||||
m_fcsNetwork->clearDestination();
|
||||
}
|
||||
|
||||
m_current.clear();
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
|
||||
if (ms < 5U)
|
||||
|
|
@ -426,23 +447,23 @@ int CYSFGateway::run()
|
|||
|
||||
rptNetwork.clearDestination();
|
||||
|
||||
if (m_gps != NULL) {
|
||||
if (m_gps != nullptr) {
|
||||
m_writer->close();
|
||||
delete m_writer;
|
||||
delete m_gps;
|
||||
}
|
||||
|
||||
if (m_ysfNetwork != NULL) {
|
||||
if (m_ysfNetwork != nullptr) {
|
||||
m_ysfNetwork->clearDestination();
|
||||
delete m_ysfNetwork;
|
||||
}
|
||||
|
||||
if (m_fcsNetwork != NULL) {
|
||||
if (m_fcsNetwork != nullptr) {
|
||||
m_fcsNetwork->close();
|
||||
delete m_fcsNetwork;
|
||||
}
|
||||
|
||||
if (m_remoteSocket != NULL) {
|
||||
if (m_remoteSocket != nullptr) {
|
||||
m_remoteSocket->close();
|
||||
delete m_remoteSocket;
|
||||
}
|
||||
|
|
@ -491,7 +512,7 @@ void CYSFGateway::createGPS()
|
|||
bool ret = m_writer->open();
|
||||
if (!ret) {
|
||||
delete m_writer;
|
||||
m_writer = NULL;
|
||||
m_writer = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +521,7 @@ void CYSFGateway::createGPS()
|
|||
|
||||
void CYSFGateway::createWiresX(CYSFNetwork* rptNetwork)
|
||||
{
|
||||
assert(rptNetwork != NULL);
|
||||
assert(rptNetwork != nullptr);
|
||||
|
||||
m_wiresX = new CWiresX(m_callsign, m_suffix, rptNetwork, *m_reflectors);
|
||||
|
||||
|
|
@ -538,17 +559,23 @@ void CYSFGateway::createWiresX(CYSFNetwork* rptNetwork)
|
|||
m_wiresX->start();
|
||||
}
|
||||
|
||||
void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool dontProcessWiresXLocal, bool wiresXCommandPassthrough)
|
||||
void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool wiresXEnabledReflector, bool wiresXCommandPassthrough)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
|
||||
WX_STATUS status;
|
||||
if (wiresXEnabledReflector && wiresXCommandPassthrough) { // If these are BOTH true, then we ignore anything but a WiresX disconnect
|
||||
status = m_wiresX->process(buffer + 35U, buffer + 14U, fich, true);
|
||||
} else { // Otherwise process all WiresX commands locally
|
||||
status = m_wiresX->process(buffer + 35U, buffer + 14U, fich, false);
|
||||
}
|
||||
|
||||
WX_STATUS status = m_wiresX->process(buffer + 35U, buffer + 14U, fich, dontProcessWiresXLocal);
|
||||
switch (status) {
|
||||
case WXS_CONNECT_YSF: {
|
||||
if (m_linkType == LINK_YSF)
|
||||
case WX_STATUS::CONNECT_YSF: {
|
||||
if (m_linkType == LINK_TYPE::YSF)
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
|
||||
if (m_linkType == LINK_FCS) {
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
m_fcsNetwork->clearDestination();
|
||||
}
|
||||
|
|
@ -562,7 +589,7 @@ void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fic
|
|||
m_current = reflector->m_id;
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_YSF;
|
||||
m_linkType = LINK_TYPE::YSF;
|
||||
|
||||
// If we are linking to a YSF2xxx mode, send the YSF2xxx gateway the link command too
|
||||
if (reflector->m_wiresX && wiresXCommandPassthrough) {
|
||||
|
|
@ -571,19 +598,19 @@ void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fic
|
|||
}
|
||||
}
|
||||
break;
|
||||
case WXS_CONNECT_FCS: {
|
||||
if (m_linkType == LINK_YSF) {
|
||||
case WX_STATUS::CONNECT_FCS: {
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
m_ysfNetwork->clearDestination();
|
||||
}
|
||||
|
||||
if (m_linkType == LINK_FCS)
|
||||
if (m_linkType == LINK_TYPE::FCS)
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
|
||||
m_current.clear();
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
|
||||
CYSFReflector* reflector = m_wiresX->getReflector();
|
||||
LogMessage("Connect to %s - \"%s\" has been requested by %10.10s", reflector->m_id.c_str(), reflector->m_name.c_str(), buffer + 14U);
|
||||
|
|
@ -595,17 +622,18 @@ void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fic
|
|||
if (ok) {
|
||||
m_current = name;
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_FCS;
|
||||
m_linkType = LINK_TYPE::FCS;
|
||||
} else {
|
||||
LogMessage("Unknown reflector - %s", name.c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WXS_DISCONNECT:
|
||||
if (m_linkType == LINK_YSF) {
|
||||
case WX_STATUS::DISCONNECT:
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
LogMessage("Disconnect has been requested by %10.10s", buffer + 14U);
|
||||
if ( (wiresXCommandPassthrough) && (::memcmp(buffer + 0U, "YSFD", 4U) == 0) ) {
|
||||
if ( (wiresXEnabledReflector && wiresXCommandPassthrough) && (::memcmp(buffer + 0U, "YSFD", 4U) == 0) ) {
|
||||
// Send the disconnect to the YSF2xxx gateway too
|
||||
LogMessage("Forward WiresX Disconnect to Network");
|
||||
m_ysfNetwork->write(buffer);
|
||||
}
|
||||
|
||||
|
|
@ -615,9 +643,9 @@ void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fic
|
|||
m_current.clear();
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
if (m_linkType == LINK_FCS) {
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
LogMessage("Disconnect has been requested by %10.10s", buffer + 14U);
|
||||
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
|
|
@ -626,7 +654,13 @@ void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fic
|
|||
m_current.clear();
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
break;
|
||||
case WX_STATUS::RECONNECT_CURRENT: {
|
||||
if (m_linkType == LINK_TYPE::NONE && !m_current.empty())
|
||||
reconnectReflector(m_current);
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -636,9 +670,9 @@ void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fic
|
|||
|
||||
void CYSFGateway::processDTMF(unsigned char* buffer, unsigned char dt)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
|
||||
WX_STATUS status = WXS_NONE;
|
||||
WX_STATUS status = WX_STATUS::NONE;
|
||||
switch (dt) {
|
||||
case YSF_DT_VD_MODE2:
|
||||
status = m_dtmf.decodeVDMode2(buffer + 35U, (buffer[34U] & 0x01U) == 0x01U);
|
||||
|
|
@ -648,16 +682,16 @@ void CYSFGateway::processDTMF(unsigned char* buffer, unsigned char dt)
|
|||
}
|
||||
|
||||
switch (status) {
|
||||
case WXS_CONNECT_YSF: {
|
||||
case WX_STATUS::CONNECT_YSF: {
|
||||
std::string id = m_dtmf.getReflector();
|
||||
CYSFReflector* reflector = m_reflectors->findById(id);
|
||||
if (reflector != NULL) {
|
||||
if (reflector != nullptr) {
|
||||
m_wiresX->processConnect(reflector);
|
||||
|
||||
if (m_linkType == LINK_YSF)
|
||||
if (m_linkType == LINK_TYPE::YSF)
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
|
||||
if (m_linkType == LINK_FCS) {
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
m_fcsNetwork->clearDestination();
|
||||
}
|
||||
|
|
@ -670,11 +704,11 @@ void CYSFGateway::processDTMF(unsigned char* buffer, unsigned char dt)
|
|||
m_current = id;
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_YSF;
|
||||
m_linkType = LINK_TYPE::YSF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WXS_CONNECT_FCS: {
|
||||
case WX_STATUS::CONNECT_FCS: {
|
||||
std::string raw = m_dtmf.getReflector();
|
||||
std::string id = "FCS00";
|
||||
std::string idShort = "FCS";
|
||||
|
|
@ -690,18 +724,18 @@ void CYSFGateway::processDTMF(unsigned char* buffer, unsigned char dt)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_linkType == LINK_YSF) {
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
m_wiresX->processDisconnect();
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
m_ysfNetwork->clearDestination();
|
||||
}
|
||||
if (m_linkType == LINK_FCS)
|
||||
if (m_linkType == LINK_TYPE::FCS)
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
|
||||
m_current.clear();
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
|
||||
LogMessage("Connect via DTMF to %s has been requested by %10.10s", id.c_str(), buffer + 14U);
|
||||
|
||||
|
|
@ -710,14 +744,14 @@ void CYSFGateway::processDTMF(unsigned char* buffer, unsigned char dt)
|
|||
m_current = id;
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_FCS;
|
||||
m_linkType = LINK_TYPE::FCS;
|
||||
} else {
|
||||
LogMessage("Unknown reflector - %s", id.c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WXS_DISCONNECT:
|
||||
if (m_linkType == LINK_YSF) {
|
||||
case WX_STATUS::DISCONNECT:
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
m_wiresX->processDisconnect();
|
||||
|
||||
LogMessage("Disconnect via DTMF has been requested by %10.10s", buffer + 14U);
|
||||
|
|
@ -728,9 +762,9 @@ void CYSFGateway::processDTMF(unsigned char* buffer, unsigned char dt)
|
|||
m_current.clear();
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
if (m_linkType == LINK_FCS) {
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
LogMessage("Disconnect via DTMF has been requested by %10.10s", buffer + 14U);
|
||||
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
|
|
@ -739,7 +773,7 @@ void CYSFGateway::processDTMF(unsigned char* buffer, unsigned char dt)
|
|||
m_current.clear();
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -800,11 +834,11 @@ std::string CYSFGateway::calculateLocator()
|
|||
void CYSFGateway::startupLinking()
|
||||
{
|
||||
if (!m_startup.empty()) {
|
||||
if (m_startup.substr(0U, 3U) == "FCS" && m_fcsNetwork != NULL) {
|
||||
if (m_startup.substr(0U, 3U) == "FCS" && m_fcsNetwork != nullptr) {
|
||||
m_current.clear();
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
|
||||
bool ok = m_fcsNetwork->writeLink(m_startup);
|
||||
m_fcsNetwork->setOptions(m_options);
|
||||
|
|
@ -815,18 +849,18 @@ void CYSFGateway::startupLinking()
|
|||
m_current = m_startup;
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_FCS;
|
||||
m_linkType = LINK_TYPE::FCS;
|
||||
} else {
|
||||
LogMessage("Unknown reflector - %s", m_startup.c_str());
|
||||
}
|
||||
} else if (m_ysfNetwork != NULL) {
|
||||
} else if (m_ysfNetwork != nullptr) {
|
||||
m_current.clear();
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
|
||||
CYSFReflector* reflector = m_reflectors->findByName(m_startup);
|
||||
if (reflector != NULL) {
|
||||
if (reflector != nullptr) {
|
||||
LogMessage("Automatic (re-)connection to %5.5s - \"%s\"", reflector->m_id.c_str(), reflector->m_name.c_str());
|
||||
|
||||
m_ysfNetwork->setOptions(m_options);
|
||||
|
|
@ -839,7 +873,7 @@ void CYSFGateway::startupLinking()
|
|||
m_current = m_startup;
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_YSF;
|
||||
m_linkType = LINK_TYPE::YSF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -847,23 +881,80 @@ void CYSFGateway::startupLinking()
|
|||
LogMessage("No connection startup");
|
||||
}
|
||||
|
||||
void CYSFGateway::reconnectReflector(const std::string& refNameOrId) {
|
||||
if (refNameOrId.substr(0U, 3U) == "FCS" && m_fcsNetwork != nullptr) {
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
|
||||
bool ok = m_fcsNetwork->writeLink(refNameOrId);
|
||||
m_fcsNetwork->setOptions(m_options);
|
||||
|
||||
if (ok) {
|
||||
LogMessage("(re-)connection to %s", refNameOrId.c_str());
|
||||
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_TYPE::FCS;
|
||||
}
|
||||
} else if (m_ysfNetwork != nullptr) {
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
|
||||
CYSFReflector* reflector = m_reflectors->findById(refNameOrId);
|
||||
if (reflector == nullptr)
|
||||
reflector = m_reflectors->findByName(refNameOrId);
|
||||
|
||||
if (reflector != nullptr) {
|
||||
LogMessage("(re-)connection to %5.5s - \"%s\"", reflector->m_id.c_str(), reflector->m_name.c_str());
|
||||
|
||||
m_wiresX->setReflector(reflector);
|
||||
|
||||
m_ysfNetwork->setDestination(reflector->m_name, reflector->m_addr, reflector->m_addrLen);
|
||||
|
||||
m_ysfNetwork->setOptions(m_options);
|
||||
m_ysfNetwork->writePoll(3U);
|
||||
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_TYPE::YSF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CYSFGateway::disconnectCurrentReflector() {
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
m_wiresX->processDisconnect();
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
m_ysfNetwork->clearDestination();
|
||||
}
|
||||
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
m_fcsNetwork->clearDestination();
|
||||
}
|
||||
|
||||
// m_current.clear();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
|
||||
void CYSFGateway::readFCSRoomsFile(const std::string& filename)
|
||||
{
|
||||
FILE* fp = ::fopen(filename.c_str(), "rt");
|
||||
if (fp == NULL)
|
||||
if (fp == nullptr)
|
||||
return;
|
||||
|
||||
unsigned int count = 0U;
|
||||
|
||||
char buffer[200U];
|
||||
while (::fgets(buffer, 200, fp) != NULL) {
|
||||
while (::fgets(buffer, 200, fp) != nullptr) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
char* p1 = ::strtok(buffer, ";");
|
||||
char* p2 = ::strtok(NULL, ";");
|
||||
char* p2 = ::strtok(nullptr, ";");
|
||||
|
||||
if (p1 != NULL && p2 != NULL) {
|
||||
if (p1 != nullptr && p2 != nullptr) {
|
||||
m_wiresX->addFCSRoom(p1, p2);
|
||||
count++;
|
||||
}
|
||||
|
|
@ -886,17 +977,17 @@ void CYSFGateway::processRemoteCommands()
|
|||
if ((::memcmp(buffer + 0U, "LinkYSF", 7U) == 0) && (strlen((char*)buffer + 0U) > 8)) {
|
||||
std::string id = std::string((char*)(buffer + 8U));
|
||||
// Left trim
|
||||
id.erase(id.begin(), std::find_if(id.begin(), id.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
id.erase(id.begin(), std::find_if(id.begin(), id.end(), [](unsigned char ch) { return !std::isspace(ch); }));
|
||||
CYSFReflector* reflector = m_reflectors->findById(id);
|
||||
if (reflector == NULL)
|
||||
if (reflector == nullptr)
|
||||
reflector = m_reflectors->findByName(id);
|
||||
if (reflector != NULL) {
|
||||
if (reflector != nullptr) {
|
||||
m_wiresX->processConnect(reflector);
|
||||
|
||||
if (m_linkType == LINK_YSF)
|
||||
if (m_linkType == LINK_TYPE::YSF)
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
|
||||
if (m_linkType == LINK_FCS) {
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
m_fcsNetwork->clearDestination();
|
||||
}
|
||||
|
|
@ -909,7 +1000,7 @@ void CYSFGateway::processRemoteCommands()
|
|||
m_current = id;
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_YSF;
|
||||
m_linkType = LINK_TYPE::YSF;
|
||||
} else {
|
||||
LogWarning("Invalid YSF reflector id/name - \"%s\"", id.c_str());
|
||||
return;
|
||||
|
|
@ -917,7 +1008,7 @@ void CYSFGateway::processRemoteCommands()
|
|||
} else if ((::memcmp(buffer + 0U, "LinkFCS", 7U) == 0) && (strlen((char*)buffer + 0U) > 8)) {
|
||||
std::string raw = std::string((char*)(buffer + 8U));
|
||||
// Left trim
|
||||
raw.erase(raw.begin(), std::find_if(raw.begin(), raw.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
raw.erase(raw.begin(), std::find_if(raw.begin(), raw.end(), [](unsigned char ch) { return !std::isspace(ch); }));
|
||||
std::string id = "FCS00";
|
||||
std::string idShort = "FCS";
|
||||
if (raw.length() == 3U) {
|
||||
|
|
@ -930,18 +1021,18 @@ void CYSFGateway::processRemoteCommands()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_linkType == LINK_YSF) {
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
m_wiresX->processDisconnect();
|
||||
m_ysfNetwork->writeUnlink(3U);
|
||||
m_ysfNetwork->clearDestination();
|
||||
}
|
||||
if (m_linkType == LINK_FCS)
|
||||
if (m_linkType == LINK_TYPE::FCS)
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
|
||||
m_current.clear();
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
|
||||
LogMessage("Connect by remote command to %s", id.c_str());
|
||||
|
||||
|
|
@ -950,12 +1041,12 @@ void CYSFGateway::processRemoteCommands()
|
|||
m_current = id;
|
||||
m_inactivityTimer.start();
|
||||
m_lostTimer.start();
|
||||
m_linkType = LINK_FCS;
|
||||
m_linkType = LINK_TYPE::FCS;
|
||||
} else {
|
||||
LogMessage("Unknown reflector - %s", id.c_str());
|
||||
}
|
||||
} else if (::memcmp(buffer + 0U, "UnLink", 6U) == 0) {
|
||||
if (m_linkType == LINK_YSF) {
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
m_wiresX->processDisconnect();
|
||||
|
||||
LogMessage("Disconnect by remote command");
|
||||
|
|
@ -966,9 +1057,9 @@ void CYSFGateway::processRemoteCommands()
|
|||
m_current.clear();
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
if (m_linkType == LINK_FCS) {
|
||||
if (m_linkType == LINK_TYPE::FCS) {
|
||||
LogMessage("Disconnect by remote command");
|
||||
|
||||
m_fcsNetwork->writeUnlink(3U);
|
||||
|
|
@ -977,13 +1068,13 @@ void CYSFGateway::processRemoteCommands()
|
|||
m_current.clear();
|
||||
m_inactivityTimer.stop();
|
||||
m_lostTimer.stop();
|
||||
m_linkType = LINK_NONE;
|
||||
m_linkType = LINK_TYPE::NONE;
|
||||
}
|
||||
} else if (::memcmp(buffer + 0U, "status", 6U) == 0) {
|
||||
std::string state = std::string("ysf:") + (((m_ysfNetwork == NULL) && (m_fcsNetwork == NULL)) ? "n/a" : ((m_linkType != LINK_NONE) ? "conn" : "disc"));
|
||||
std::string state = std::string("ysf:") + (((m_ysfNetwork == nullptr) && (m_fcsNetwork == nullptr)) ? "n/a" : ((m_linkType != LINK_TYPE::NONE) ? "conn" : "disc"));
|
||||
m_remoteSocket->write((unsigned char*)state.c_str(), (unsigned int)state.length(), addr, addrLen);
|
||||
} else if (::memcmp(buffer + 0U, "host", 4U) == 0) {
|
||||
std::string ref = ((((m_ysfNetwork == NULL) && (m_fcsNetwork == NULL)) || (m_linkType == LINK_NONE)) ? "NONE" : m_current);
|
||||
std::string ref = ((((m_ysfNetwork == nullptr) && (m_fcsNetwork == nullptr)) || (m_linkType == LINK_TYPE::NONE)) ? "NONE" : m_current);
|
||||
std::string host = std::string("ysf:\"") + ref + "\"";
|
||||
m_remoteSocket->write((unsigned char*)host.c_str(), (unsigned int)host.length(), addr, addrLen);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2018,2020,2025 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
|
||||
|
|
@ -32,10 +32,10 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
enum LINK_TYPE {
|
||||
LINK_NONE,
|
||||
LINK_YSF,
|
||||
LINK_FCS
|
||||
enum class LINK_TYPE {
|
||||
NONE,
|
||||
YSF,
|
||||
FCS
|
||||
};
|
||||
|
||||
class CYSFGateway
|
||||
|
|
@ -68,8 +68,10 @@ private:
|
|||
CUDPSocket* m_remoteSocket;
|
||||
|
||||
void startupLinking();
|
||||
void reconnectReflector(const std::string& nameOrId);
|
||||
void disconnectCurrentReflector();
|
||||
std::string calculateLocator();
|
||||
void processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool dontProcessWiresXLocal, bool wiresXCommandPassthrough);
|
||||
void processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool wiresXEnabledReflector, bool wiresXCommandPassthrough);
|
||||
void processDTMF(unsigned char* buffer, unsigned char dt);
|
||||
void createWiresX(CYSFNetwork* rptNetwork);
|
||||
void createGPS();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ RptAddress=127.0.0.1
|
|||
RptPort=3200
|
||||
LocalAddress=127.0.0.1
|
||||
LocalPort=4200
|
||||
WiresXMakeUpper=1
|
||||
WiresXCommandPassthrough=0
|
||||
Debug=0
|
||||
Daemon=0
|
||||
|
|
@ -44,6 +43,7 @@ Suffix=Y
|
|||
# book DG-ID for Reflector
|
||||
# Options=20;21;
|
||||
InactivityTimeout=10
|
||||
Reconnect=0
|
||||
Revert=0
|
||||
Debug=0
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -108,6 +111,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
|
@ -126,6 +132,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -144,6 +153,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="APRSWriter.h" />
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
43
YSFGateway/YSFHostsUpdate.sh
Normal file
43
YSFGateway/YSFHostsUpdate.sh
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#! /bin/bash
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2025 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.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# Full path to the YSFHosts hosts file
|
||||
#
|
||||
YSFHOSTS=/path/to/YSFHosts.txt
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Do not edit below here
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Check we are root
|
||||
if [ "$(id -u)" != "0" ]
|
||||
then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download the YSFHosts.txt file
|
||||
curl --fail --silent -S -L -o ${YSFHOSTS} -A "YSFGateway - G4KLX" https://hostfiles.refcheck.radio/YSFHosts.txt
|
||||
|
||||
exit 0
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# YSFHostsupdate.sh
|
||||
#
|
||||
# Copyright (C) 2016 by Tony Corbett G0WFV
|
||||
# Adapted to YSFHosts by Paul Nannery KC2VRJ on 6/28/2016 with all crdeit
|
||||
# to G0WFV for the orignal script.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# On a Linux based system, such as a Raspberry Pi, this script will perform all
|
||||
# the steps required to maintain the YSFHosts.txt (or similar) file for you.
|
||||
#
|
||||
# It is designed to run from crontab and will download the YSFHosts from the
|
||||
# master ysfreflector.de database and optionally keep a backup of previously
|
||||
# created files for you.
|
||||
#
|
||||
# It will also prune the number of backup files according to a value specified
|
||||
# by you in the configuration below.
|
||||
#
|
||||
# To install in root's crontab use the command ...
|
||||
#
|
||||
# sudo crontab -e
|
||||
#
|
||||
# ... and add the following line to the bottom of the file ...
|
||||
#
|
||||
# 0 0 * * * /path/to/script/YSFHostsupdate.sh 1>/dev/null 2>&1
|
||||
#
|
||||
# ... where /path/to/script/ should be replaced by the path to this script.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# CONFIGURATION
|
||||
#
|
||||
# Full path to YSFHosts
|
||||
YSFHOSTS=/path/to/YSFHosts.txt
|
||||
|
||||
# How many YSFHosts files do you want backed up (0 = do not keep backups)
|
||||
YSFHOSTSFILEBACKUP=1
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Do not edit below here
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Check we are root
|
||||
if [ "$(id -u)" != "0" ]
|
||||
then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create backup of old file
|
||||
if [ ${YSFHOSTSFILEBACKUP} -ne 0 ]
|
||||
then
|
||||
cp ${YSFHOSTS} ${YSFHOSTS}.$(date +%d%m%y)
|
||||
fi
|
||||
|
||||
# Prune backups
|
||||
BACKUPCOUNT=$(ls ${YSFHOSTS}.* | wc -l)
|
||||
BACKUPSTODELETE=$(expr ${BACKUPCOUNT} - ${YSFHOSTSFILEBACKUP})
|
||||
|
||||
if [ ${BACKUPCOUNT} -gt ${YSFHOSTSFILEBACKUP} ]
|
||||
then
|
||||
for f in $(ls -tr ${YSFHOSTS}.* | head -${BACKUPSTODELETE})
|
||||
do
|
||||
rm -f $f
|
||||
done
|
||||
fi
|
||||
|
||||
# Generate YSFHosts.txt file
|
||||
curl https://register.ysfreflector.de/export_csv.php > ${YSFHOSTS}
|
||||
|
||||
exit 0
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2014,2016,2017,2018,2020,2025 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
|
||||
|
|
@ -32,10 +32,10 @@ m_socket(address, port),
|
|||
m_debug(debug),
|
||||
m_addr(),
|
||||
m_addrLen(0U),
|
||||
m_poll(NULL),
|
||||
m_options(NULL),
|
||||
m_poll(nullptr),
|
||||
m_options(nullptr),
|
||||
m_opt(),
|
||||
m_unlink(NULL),
|
||||
m_unlink(nullptr),
|
||||
m_buffer(1000U, "YSF Network Buffer"),
|
||||
m_pollTimer(1000U, 5U),
|
||||
m_name(),
|
||||
|
|
@ -65,10 +65,10 @@ m_socket(port),
|
|||
m_debug(debug),
|
||||
m_addr(),
|
||||
m_addrLen(0U),
|
||||
m_poll(NULL),
|
||||
m_options(NULL),
|
||||
m_poll(nullptr),
|
||||
m_options(nullptr),
|
||||
m_opt(),
|
||||
m_unlink(NULL),
|
||||
m_unlink(nullptr),
|
||||
m_buffer(1000U, "YSF Network Buffer"),
|
||||
m_pollTimer(1000U, 5U),
|
||||
m_name(),
|
||||
|
|
@ -119,6 +119,8 @@ bool CYSFNetwork::setDestination(const std::string& name, const sockaddr_storage
|
|||
m_addrLen = addrLen;
|
||||
m_linked = false;
|
||||
|
||||
close();
|
||||
|
||||
bool ret = open();
|
||||
if (ret) {
|
||||
m_pollTimer.start();
|
||||
|
|
@ -140,7 +142,7 @@ void CYSFNetwork::clearDestination()
|
|||
|
||||
void CYSFNetwork::write(const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_addrLen == 0U)
|
||||
return;
|
||||
|
|
@ -249,7 +251,7 @@ void CYSFNetwork::clock(unsigned int ms)
|
|||
|
||||
unsigned int CYSFNetwork::read(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_buffer.isEmpty())
|
||||
return 0U;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2016,2025 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -86,8 +86,8 @@ CYSFPayload::~CYSFPayload()
|
|||
|
||||
bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -131,8 +131,8 @@ bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
|||
|
||||
bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -176,8 +176,8 @@ bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
|||
|
||||
bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
|
||||
|
|
@ -223,8 +223,8 @@ bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char*
|
|||
|
||||
bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
|
||||
|
|
@ -270,8 +270,8 @@ bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char*
|
|||
|
||||
void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* d
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned char bytes[45U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
|
@ -314,8 +314,8 @@ void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* d
|
|||
|
||||
void CYSFPayload::writeDataFRModeData2(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
assert(dt != nullptr);
|
||||
assert(data != nullptr);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
|
|
@ -331,7 +331,7 @@ void CYSFPayload::writeDataFRModeData2(const unsigned char* dt, unsigned char* d
|
|||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned char bytes[45U] = { 0x00U };
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016-2021,2025 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
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
CYSFReflectors::CYSFReflectors(const std::string& hostsFile, unsigned int reloadTime, bool makeUpper) :
|
||||
CYSFReflectors::CYSFReflectors(const std::string& hostsFile, unsigned int reloadTime) :
|
||||
m_hostsFile(hostsFile),
|
||||
m_parrotAddress(),
|
||||
m_parrotPort(0U),
|
||||
|
|
@ -40,7 +40,6 @@ m_fcsRooms(),
|
|||
m_newReflectors(),
|
||||
m_currReflectors(),
|
||||
m_search(),
|
||||
m_makeUpper(makeUpper),
|
||||
m_timer(1000U, reloadTime * 60U)
|
||||
{
|
||||
if (reloadTime > 0U)
|
||||
|
|
@ -61,8 +60,8 @@ CYSFReflectors::~CYSFReflectors()
|
|||
|
||||
static bool refComparison(const CYSFReflector* r1, const CYSFReflector* r2)
|
||||
{
|
||||
assert(r1 != NULL);
|
||||
assert(r2 != NULL);
|
||||
assert(r1 != nullptr);
|
||||
assert(r2 != nullptr);
|
||||
|
||||
std::string name1 = r1->m_name;
|
||||
std::string name2 = r2->m_name;
|
||||
|
|
@ -113,20 +112,20 @@ bool CYSFReflectors::load()
|
|||
m_newReflectors.clear();
|
||||
|
||||
FILE* fp = ::fopen(m_hostsFile.c_str(), "rt");
|
||||
if (fp != NULL) {
|
||||
if (fp != nullptr) {
|
||||
char buffer[100U];
|
||||
while (::fgets(buffer, 100U, fp) != NULL) {
|
||||
while (::fgets(buffer, 100U, fp) != nullptr) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
char* p1 = ::strtok(buffer, ";\r\n");
|
||||
char* p2 = ::strtok(NULL, ";\r\n");
|
||||
char* p3 = ::strtok(NULL, ";\r\n");
|
||||
char* p4 = ::strtok(NULL, ";\r\n");
|
||||
char* p5 = ::strtok(NULL, ";\r\n");
|
||||
char* p6 = ::strtok(NULL, "\r\n");
|
||||
char* p2 = ::strtok(nullptr, ";\r\n");
|
||||
char* p3 = ::strtok(nullptr, ";\r\n");
|
||||
char* p4 = ::strtok(nullptr, ";\r\n");
|
||||
char* p5 = ::strtok(nullptr, ";\r\n");
|
||||
char* p6 = ::strtok(nullptr, "\r\n");
|
||||
|
||||
if (p1 != NULL && p2 != NULL && p3 != NULL && p4 != NULL && p5 != NULL && p6 != NULL) {
|
||||
if (p1 != nullptr && p2 != nullptr && p3 != nullptr && p4 != nullptr && p5 != nullptr && p6 != nullptr) {
|
||||
std::string host = std::string(p4);
|
||||
unsigned short port = (unsigned short)::atoi(p5);
|
||||
|
||||
|
|
@ -141,9 +140,8 @@ bool CYSFReflectors::load()
|
|||
refl->m_addr = addr;
|
||||
refl->m_addrLen = addrLen;
|
||||
refl->m_count = std::string(p6);
|
||||
refl->m_type = YT_YSF;
|
||||
refl->m_wiresX = (refl->m_name.compare(0, 3, "XLX") == 0);
|
||||
|
||||
refl->m_type = YSF_TYPE::YSF;
|
||||
refl->m_wiresX = ( refl->m_name.compare(0, 3, "XLX") == 0 || refl->m_name.compare(2, 4, "-XLX") == 0 );
|
||||
refl->m_name.resize(16U, ' ');
|
||||
refl->m_desc.resize(14U, ' ');
|
||||
|
||||
|
|
@ -172,7 +170,7 @@ bool CYSFReflectors::load()
|
|||
refl->m_addr = addr;
|
||||
refl->m_addrLen = addrLen;
|
||||
refl->m_count = "000";
|
||||
refl->m_type = YT_YSF;
|
||||
refl->m_type = YSF_TYPE::YSF;
|
||||
refl->m_wiresX = false;
|
||||
|
||||
m_newReflectors.push_back(refl);
|
||||
|
|
@ -195,7 +193,7 @@ bool CYSFReflectors::load()
|
|||
refl->m_addr = addr;
|
||||
refl->m_addrLen = addrLen;
|
||||
refl->m_count = "000";
|
||||
refl->m_type = YT_YSF;
|
||||
refl->m_type = YSF_TYPE::YSF;
|
||||
refl->m_wiresX = true;
|
||||
|
||||
m_newReflectors.push_back(refl);
|
||||
|
|
@ -218,7 +216,7 @@ bool CYSFReflectors::load()
|
|||
refl->m_addr = addr;
|
||||
refl->m_addrLen = addrLen;
|
||||
refl->m_count = "000";
|
||||
refl->m_type = YT_YSF;
|
||||
refl->m_type = YSF_TYPE::YSF;
|
||||
refl->m_wiresX = true;
|
||||
|
||||
m_newReflectors.push_back(refl);
|
||||
|
|
@ -241,7 +239,7 @@ bool CYSFReflectors::load()
|
|||
refl->m_addr = addr;
|
||||
refl->m_addrLen = addrLen;
|
||||
refl->m_count = "000";
|
||||
refl->m_type = YT_YSF;
|
||||
refl->m_type = YSF_TYPE::YSF;
|
||||
refl->m_wiresX = true;
|
||||
|
||||
m_newReflectors.push_back(refl);
|
||||
|
|
@ -272,7 +270,7 @@ bool CYSFReflectors::load()
|
|||
refl->m_desc = desc;
|
||||
refl->m_addrLen = 0U;
|
||||
refl->m_count = "000";
|
||||
refl->m_type = YT_FCS;
|
||||
refl->m_type = YSF_TYPE::FCS;
|
||||
refl->m_wiresX = false;
|
||||
|
||||
refl->m_name.resize(16U, ' ');
|
||||
|
|
@ -285,13 +283,6 @@ bool CYSFReflectors::load()
|
|||
if (size == 0U)
|
||||
return false;
|
||||
|
||||
if (m_makeUpper) {
|
||||
for (std::vector<CYSFReflector*>::iterator it = m_newReflectors.begin(); it != m_newReflectors.end(); ++it) {
|
||||
std::transform((*it)->m_name.begin(), (*it)->m_name.end(), (*it)->m_name.begin(), ::toupper);
|
||||
std::transform((*it)->m_desc.begin(), (*it)->m_desc.end(), (*it)->m_desc.begin(), ::toupper);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(m_newReflectors.begin(), m_newReflectors.end(), refComparison);
|
||||
|
||||
return true;
|
||||
|
|
@ -306,7 +297,7 @@ CYSFReflector* CYSFReflectors::findById(const std::string& id)
|
|||
|
||||
LogMessage("Trying to find non existent YSF reflector with an id of %s", id.c_str());
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CYSFReflectors::findById(unsigned int id) const
|
||||
|
|
@ -325,9 +316,6 @@ bool CYSFReflectors::findById(unsigned int id) const
|
|||
CYSFReflector* CYSFReflectors::findByName(const std::string& name)
|
||||
{
|
||||
std::string fullName = name;
|
||||
if (m_makeUpper) {
|
||||
std::transform(fullName.begin(), fullName.end(), fullName.begin(), ::toupper);
|
||||
}
|
||||
fullName.resize(16U, ' ');
|
||||
|
||||
for (std::vector<CYSFReflector*>::const_iterator it = m_currReflectors.cbegin(); it != m_currReflectors.cend(); ++it) {
|
||||
|
|
@ -337,7 +325,7 @@ CYSFReflector* CYSFReflectors::findByName(const std::string& name)
|
|||
|
||||
LogMessage("Trying to find non existent YSF reflector with a name of %s", name.c_str());
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<CYSFReflector*>& CYSFReflectors::current()
|
||||
|
|
@ -350,7 +338,7 @@ std::vector<CYSFReflector*>& CYSFReflectors::search(const std::string& name)
|
|||
m_search.clear();
|
||||
|
||||
std::string trimmed = name;
|
||||
trimmed.erase(std::find_if(trimmed.rbegin(), trimmed.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), trimmed.end());
|
||||
trimmed.erase(std::find_if(trimmed.rbegin(), trimmed.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), trimmed.end());
|
||||
std::transform(trimmed.begin(), trimmed.end(), trimmed.begin(), ::toupper);
|
||||
|
||||
// Removed now un-used variable
|
||||
|
|
@ -358,13 +346,13 @@ std::vector<CYSFReflector*>& CYSFReflectors::search(const std::string& name)
|
|||
|
||||
for (std::vector<CYSFReflector*>::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<int, int>(std::isspace))).base(), reflector.end());
|
||||
reflector.erase(std::find_if(reflector.rbegin(), reflector.rend(),[](unsigned char ch) { return !std::isspace(ch); }).base(),reflector.end());
|
||||
std::transform(reflector.begin(), reflector.end(), reflector.begin(), ::toupper);
|
||||
|
||||
// Original match function - only matches start of string.
|
||||
// if (trimmed == reflector.substr(0U, len))
|
||||
// m_search.push_back(*it);
|
||||
|
||||
|
||||
// New match function searches the whole string
|
||||
for (unsigned int refSrcPos = 0U; refSrcPos < reflector.length(); refSrcPos++) {
|
||||
if (reflector.substr(refSrcPos, trimmed.length()) == trimmed) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016-2021,2025 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
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
enum YSF_TYPE {
|
||||
YT_YSF,
|
||||
YT_FCS
|
||||
enum class YSF_TYPE {
|
||||
YSF,
|
||||
FCS
|
||||
};
|
||||
|
||||
class CYSFReflector {
|
||||
|
|
@ -39,7 +39,7 @@ public:
|
|||
m_count("000"),
|
||||
m_addr(),
|
||||
m_addrLen(0U),
|
||||
m_type(YT_YSF),
|
||||
m_type(YSF_TYPE::YSF),
|
||||
m_wiresX(false)
|
||||
{
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
class CYSFReflectors {
|
||||
public:
|
||||
CYSFReflectors(const std::string& hostsFile, unsigned int reloadTime, bool makeUpper);
|
||||
CYSFReflectors(const std::string& hostsFile, unsigned int reloadTime);
|
||||
~CYSFReflectors();
|
||||
|
||||
void setParrot(const std::string& address, unsigned short port);
|
||||
|
|
@ -92,7 +92,6 @@ private:
|
|||
std::vector<CYSFReflector*> m_newReflectors;
|
||||
std::vector<CYSFReflector*> m_currReflectors;
|
||||
std::vector<CYSFReflector*> m_search;
|
||||
bool m_makeUpper;
|
||||
CTimer m_timer;
|
||||
|
||||
bool findById(unsigned int id) const;
|
||||
|
|
|
|||
38
YSFGateway/prebuild.cmd
Normal file
38
YSFGateway/prebuild.cmd
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
@echo off
|
||||
REM This pre-build file is for MSVS VC++. It parses the git master hash and
|
||||
REM converts it into GitVersion.h for compiling into builds. [George M1GEO]
|
||||
|
||||
cd %1
|
||||
setlocal enabledelayedexpansion
|
||||
set HEADFILE=..\.git\HEAD
|
||||
set HASHFILE=0
|
||||
if exist %HEADFILE% (
|
||||
for /F "tokens=4 delims=/:" %%a in ('type %HEADFILE%') do set HEADBRANCH=%%a
|
||||
set HASHFILE=..\.git\refs\heads\!HEADBRANCH!
|
||||
echo Found Git HEAD file: %HEADFILE%
|
||||
echo Git HEAD branch: !HEADBRANCH!
|
||||
echo Git HASH file: !HASHFILE!
|
||||
call :USEHASH
|
||||
) else (
|
||||
echo No head file :(
|
||||
call :USENULL
|
||||
)
|
||||
|
||||
goto :EOF
|
||||
|
||||
:USENULL
|
||||
set GITHASH=0000000000000000000000000000000000000000
|
||||
goto :WRITEGITVERSIONHEADER
|
||||
|
||||
:USEHASH
|
||||
for /f %%i in ('type !HASHFILE!') do set GITHASH=%%i
|
||||
goto :WRITEGITVERSIONHEADER
|
||||
|
||||
:WRITEGITVERSIONHEADER
|
||||
echo // File contains Git commit ID SHA1 present at buildtime (prebuild.cmd) > GitVersion.h
|
||||
echo const char *gitversion = "%GITHASH%"; >> GitVersion.h
|
||||
echo Current Git HASH: %GITHASH%
|
||||
goto :FINISHED
|
||||
|
||||
:FINISHED
|
||||
echo GitVersion.h written...
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2014,2016,2018,2020,2025 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
|
||||
|
|
@ -47,7 +47,7 @@ bool CNetwork::write(const unsigned char* data)
|
|||
if (m_addrLen == 0U)
|
||||
return true;
|
||||
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
return m_socket.write(data, 155U, m_addr, m_addrLen);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2025 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
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#include <cstring>
|
||||
|
||||
CParrot::CParrot(unsigned int timeout) :
|
||||
m_data(NULL),
|
||||
m_data(nullptr),
|
||||
m_length(timeout * 1550U + 1000U),
|
||||
m_used(0U),
|
||||
m_ptr(0U)
|
||||
|
|
@ -40,7 +40,7 @@ CParrot::~CParrot()
|
|||
|
||||
bool CParrot::write(const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if ((m_length - m_used) < 1000U)
|
||||
return false;
|
||||
|
|
@ -64,7 +64,7 @@ void CParrot::clear()
|
|||
|
||||
unsigned int CParrot::read(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (m_used == 0U)
|
||||
return 0U;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2018,2025 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
|
||||
|
|
@ -77,7 +77,7 @@ CStopWatch::~CStopWatch()
|
|||
unsigned long long CStopWatch::time() const
|
||||
{
|
||||
struct timeval now;
|
||||
::gettimeofday(&now, NULL);
|
||||
::gettimeofday(&now, nullptr);
|
||||
|
||||
return now.tv_sec * 1000ULL + now.tv_usec / 1000ULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2025 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,9 +31,9 @@ CThread::~CThread()
|
|||
|
||||
bool CThread::run()
|
||||
{
|
||||
m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL);
|
||||
m_handle = ::CreateThread(nullptr, 0, &helper, this, 0, nullptr);
|
||||
|
||||
return m_handle != NULL;
|
||||
return m_handle != nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -74,13 +74,13 @@ CThread::~CThread()
|
|||
|
||||
bool CThread::run()
|
||||
{
|
||||
return ::pthread_create(&m_thread, NULL, helper, this) == 0;
|
||||
return ::pthread_create(&m_thread, nullptr, helper, this) == 0;
|
||||
}
|
||||
|
||||
|
||||
void CThread::wait()
|
||||
{
|
||||
::pthread_join(m_thread, NULL);
|
||||
::pthread_join(m_thread, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ void* CThread::helper(void* arg)
|
|||
|
||||
p->entry();
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CThread::sleep(unsigned int ms)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2006-2016,2020,2024,2025 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,29 +34,27 @@
|
|||
#endif
|
||||
|
||||
CUDPSocket::CUDPSocket(const std::string& address, unsigned short port) :
|
||||
m_address_save(address),
|
||||
m_port_save(port),
|
||||
m_counter(0U)
|
||||
m_localAddress(address),
|
||||
m_localPort(port),
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
m_fd(INVALID_SOCKET),
|
||||
#else
|
||||
m_fd(-1),
|
||||
#endif
|
||||
m_af(AF_UNSPEC)
|
||||
{
|
||||
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 short port) :
|
||||
m_address_save(),
|
||||
m_port_save(port),
|
||||
m_counter(0U)
|
||||
m_localAddress(),
|
||||
m_localPort(port),
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
m_fd(INVALID_SOCKET),
|
||||
#else
|
||||
m_fd(-1),
|
||||
#endif
|
||||
m_af(AF_UNSPEC)
|
||||
{
|
||||
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()
|
||||
|
|
@ -93,10 +91,10 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
|
|||
std::string portstr = std::to_string(port);
|
||||
struct addrinfo *res;
|
||||
|
||||
/* port is always digits, no needs to lookup service */
|
||||
/* 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);
|
||||
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));
|
||||
|
|
@ -107,9 +105,11 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
|
|||
return err;
|
||||
}
|
||||
|
||||
::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen);
|
||||
address_length = (unsigned int)res->ai_addrlen;
|
||||
|
||||
freeaddrinfo(res);
|
||||
::memcpy(&addr, res->ai_addr, address_length);
|
||||
|
||||
::freeaddrinfo(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -119,35 +119,35 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
|
|||
if (addr1.ss_family != addr2.ss_family)
|
||||
return false;
|
||||
|
||||
if (type == IMT_ADDRESS_AND_PORT) {
|
||||
if (type == IPMATCHTYPE::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;
|
||||
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) {
|
||||
} else if (type == IPMATCHTYPE::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;
|
||||
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;
|
||||
|
|
@ -163,35 +163,38 @@ bool CUDPSocket::isNone(const sockaddr_storage& addr)
|
|||
|
||||
bool CUDPSocket::open(const sockaddr_storage& address)
|
||||
{
|
||||
return open(address.ss_family);
|
||||
m_af = address.ss_family;
|
||||
|
||||
return open();
|
||||
}
|
||||
|
||||
bool CUDPSocket::open(unsigned int af)
|
||||
bool CUDPSocket::open()
|
||||
{
|
||||
return open(0, af, m_address_save, m_port_save);
|
||||
}
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
assert(m_fd == INVALID_SOCKET);
|
||||
#else
|
||||
assert(m_fd == -1);
|
||||
#endif
|
||||
|
||||
bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port)
|
||||
{
|
||||
sockaddr_storage addr;
|
||||
unsigned int addrlen;
|
||||
struct addrinfo hints;
|
||||
|
||||
::memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = af;
|
||||
hints.ai_family = m_af;
|
||||
|
||||
/* to determine protocol family, call lookup() first. */
|
||||
int err = lookup(address, port, addr, addrlen, hints);
|
||||
// To determine protocol family, call lookup() on the local address first.
|
||||
int err = lookup(m_localAddress, m_localPort, addr, addrlen, hints);
|
||||
if (err != 0) {
|
||||
LogError("The local address is invalid - %s", address.c_str());
|
||||
LogError("The local address is invalid - %s", m_localAddress.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
close(index);
|
||||
m_af = addr.ss_family;
|
||||
|
||||
int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
m_fd = ::socket(m_af, SOCK_DGRAM, 0);
|
||||
if (m_fd < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Cannot create the UDP socket, err: %lu", ::GetLastError());
|
||||
#else
|
||||
|
|
@ -200,62 +203,58 @@ bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std
|
|||
return false;
|
||||
}
|
||||
|
||||
m_address[index] = address;
|
||||
m_port[index] = port;
|
||||
m_af[index] = addr.ss_family;
|
||||
m_fd[index] = fd;
|
||||
|
||||
if (port > 0U) {
|
||||
if (m_localPort > 0U) {
|
||||
int reuse = 1;
|
||||
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
|
||||
if (::setsockopt(m_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
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) {
|
||||
if (::bind(m_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
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo("Opening UDP port on %hu", port);
|
||||
LogInfo("Opening UDP port on %hu", m_localPort);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length)
|
||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
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)
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (m_fd == INVALID_SOCKET)
|
||||
return 0;
|
||||
#else
|
||||
if (m_fd == -1)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
// Check that the readfrom() won't block
|
||||
struct pollfd pfd;
|
||||
pfd.fd = m_fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
|
||||
// Return immediately
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int ret = WSAPoll(pfd, n, 0);
|
||||
int ret = WSAPoll(&pfd, 1, 0);
|
||||
#else
|
||||
int ret = ::poll(pfd, n, 0);
|
||||
int ret = ::poll(&pfd, 1, 0);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -266,14 +265,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
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)
|
||||
if ((pfd.revents & POLLIN) == 0)
|
||||
return 0;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -283,9 +275,9 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
#else
|
||||
ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
|
@ -294,7 +286,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
LogError("Error returned from recvfrom, err: %d", errno);
|
||||
|
||||
if (len == -1 && errno == ENOTSOCK) {
|
||||
LogMessage("Re-opening UDP port on %hu", m_port[index]);
|
||||
LogMessage("Re-opening UDP port on %hu", m_localPort);
|
||||
close();
|
||||
open();
|
||||
}
|
||||
|
|
@ -302,43 +294,43 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
|
|||
return -1;
|
||||
}
|
||||
|
||||
m_counter++;
|
||||
address_length = size;
|
||||
addressLength = size;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length)
|
||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer != nullptr);
|
||||
assert(length > 0U);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
assert(m_fd != INVALID_SOCKET);
|
||||
#else
|
||||
assert(m_fd >= 0);
|
||||
#endif
|
||||
|
||||
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);
|
||||
int ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
|
||||
#else
|
||||
ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
|
||||
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Error returned from sendto, err: %lu", ::GetLastError());
|
||||
LogError("Error returned from sendto, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Error returned from sendto, err: %d", errno);
|
||||
LogError("Error returned from sendto, err: %d", errno);
|
||||
#endif
|
||||
} else {
|
||||
} else {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (ret == int(length))
|
||||
result = true;
|
||||
if (ret == int(length))
|
||||
result = true;
|
||||
#else
|
||||
if (ret == ssize_t(length))
|
||||
result = true;
|
||||
if (ret == ssize_t(length))
|
||||
result = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -346,18 +338,16 @@ bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const s
|
|||
|
||||
void CUDPSocket::close()
|
||||
{
|
||||
for (unsigned int i = 0; i < UDP_SOCKET_MAX; i++)
|
||||
close(i);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (m_fd != INVALID_SOCKET) {
|
||||
::closesocket(m_fd);
|
||||
m_fd = INVALID_SOCKET;
|
||||
}
|
||||
#else
|
||||
if (m_fd >= 0) {
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2011,2013,2015,2016,2020,2024,2025 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,13 +35,9 @@
|
|||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#if !defined(UDP_SOCKET_MAX)
|
||||
#define UDP_SOCKET_MAX 1
|
||||
#endif
|
||||
|
||||
enum IPMATCHTYPE {
|
||||
IMT_ADDRESS_AND_PORT,
|
||||
IMT_ADDRESS_ONLY
|
||||
enum class IPMATCHTYPE {
|
||||
ADDRESS_AND_PORT,
|
||||
ADDRESS_ONLY
|
||||
};
|
||||
|
||||
class CUDPSocket {
|
||||
|
|
@ -50,34 +46,34 @@ public:
|
|||
CUDPSocket(unsigned short port = 0U);
|
||||
~CUDPSocket();
|
||||
|
||||
bool open(unsigned int af = AF_UNSPEC);
|
||||
bool open();
|
||||
bool open(const sockaddr_storage& address);
|
||||
bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short 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);
|
||||
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength);
|
||||
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength);
|
||||
|
||||
void close();
|
||||
void close(const unsigned int index);
|
||||
|
||||
static void startup();
|
||||
static void shutdown();
|
||||
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength);
|
||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength, struct addrinfo& hints);
|
||||
|
||||
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
|
||||
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IPMATCHTYPE::ADDRESS_AND_PORT);
|
||||
|
||||
static bool isNone(const sockaddr_storage& addr);
|
||||
|
||||
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;
|
||||
std::string m_localAddress;
|
||||
unsigned short m_localPort;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SOCKET m_fd;
|
||||
int m_af;
|
||||
#else
|
||||
int m_fd;
|
||||
sa_family_t m_af;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2020,2024,2025 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
|
||||
|
|
@ -19,6 +19,6 @@
|
|||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
const char* VERSION = "20201101";
|
||||
const char* VERSION = "20250607";
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -108,6 +111,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
|
@ -126,6 +132,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -144,6 +153,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>prebuild.cmd</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="StopWatch.h" />
|
||||
|
|
|
|||
38
YSFParrot/prebuild.cmd
Normal file
38
YSFParrot/prebuild.cmd
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
@echo off
|
||||
REM This pre-build file is for MSVS VC++. It parses the git master hash and
|
||||
REM converts it into GitVersion.h for compiling into builds. [George M1GEO]
|
||||
|
||||
cd %1
|
||||
setlocal enabledelayedexpansion
|
||||
set HEADFILE=..\.git\HEAD
|
||||
set HASHFILE=0
|
||||
if exist %HEADFILE% (
|
||||
for /F "tokens=4 delims=/:" %%a in ('type %HEADFILE%') do set HEADBRANCH=%%a
|
||||
set HASHFILE=..\.git\refs\heads\!HEADBRANCH!
|
||||
echo Found Git HEAD file: %HEADFILE%
|
||||
echo Git HEAD branch: !HEADBRANCH!
|
||||
echo Git HASH file: !HASHFILE!
|
||||
call :USEHASH
|
||||
) else (
|
||||
echo No head file :(
|
||||
call :USENULL
|
||||
)
|
||||
|
||||
goto :EOF
|
||||
|
||||
:USENULL
|
||||
set GITHASH=0000000000000000000000000000000000000000
|
||||
goto :WRITEGITVERSIONHEADER
|
||||
|
||||
:USEHASH
|
||||
for /f %%i in ('type !HASHFILE!') do set GITHASH=%%i
|
||||
goto :WRITEGITVERSIONHEADER
|
||||
|
||||
:WRITEGITVERSIONHEADER
|
||||
echo // File contains Git commit ID SHA1 present at buildtime (prebuild.cmd) > GitVersion.h
|
||||
echo const char *gitversion = "%GITHASH%"; >> GitVersion.h
|
||||
echo Current Git HASH: %GITHASH%
|
||||
goto :FINISHED
|
||||
|
||||
:FINISHED
|
||||
echo GitVersion.h written...
|
||||
Loading…
Reference in a new issue