diff --git a/Conf.cpp b/Conf.cpp index 7c51223..a164587 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018,2020,2023 by Jonathan Naylor G4KLX + * Copyright (C) 2018,2020,2023,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,12 +26,12 @@ const int BUFFER_SIZE = 500; -enum SECTION { - SECTION_NONE, - SECTION_GENERAL, - SECTION_LOG, - SECTION_MQTT, - SECTION_DAPNET +enum class SECTION { + NONE, + GENERAL, + LOG, + MQTT, + DAPNET }; CConf::CConf(const std::string& file) : @@ -65,39 +65,39 @@ 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, "[Log]", 5U) == 0) - section = SECTION_LOG; + section = SECTION::LOG; else if (::strncmp(buffer, "[MQTT]", 6U) == 0) - section = SECTION_MQTT; + section = SECTION::MQTT; else if (::strncmp(buffer, "[DAPNET]", 8U) == 0) - section = SECTION_DAPNET; + section = SECTION::DAPNET; 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 @@ -109,7 +109,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 @@ -117,32 +117,29 @@ bool CConf::read() *p = '\0'; } - if (section == SECTION_GENERAL) { + if (section == SECTION::GENERAL) { if (::strcmp(key, "Callsign") == 0) { for (unsigned int i = 0U; value[i] != '\0'; i++) { if (!::isspace(value[i])) m_callsign.insert(m_callsign.end(), 1, value[i]); } - } - else if (::strcmp(key, "WhiteList") == 0) { + } else if (::strcmp(key, "WhiteList") == 0) { char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { + while (p != nullptr) { unsigned int ric = (unsigned int)::atoi(p); if (ric > 0U) m_whiteList.push_back(ric); - p = ::strtok(NULL, ",\r\n"); + p = ::strtok(nullptr, ",\r\n"); } - } - else if (::strcmp(key, "BlackList") == 0) { + } else if (::strcmp(key, "BlackList") == 0) { char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { + while (p != nullptr) { unsigned int ric = (unsigned int)::atoi(p); if (ric > 0U) m_blackList.push_back(ric); - p = ::strtok(NULL, ",\r\n"); + p = ::strtok(nullptr, ",\r\n"); } - } - else if (::strcmp(key,"BlacklistRegexfile") == 0) + } else if (::strcmp(key,"BlacklistRegexfile") == 0) m_blacklistRegexfile = value; else if (::strcmp(key,"WhitelistRegexfile") == 0) m_whitelistRegexfile = value; @@ -156,12 +153,12 @@ bool CConf::read() m_myPort = (unsigned short)::atoi(value); else if (::strcmp(key, "Daemon") == 0) m_daemon = ::atoi(value) == 1; - } else if (section == SECTION_LOG) { + } else if (section == SECTION::LOG) { if (::strcmp(key, "MQTTLevel") == 0) m_logMQTTLevel = (unsigned int)::atoi(value); else if (::strcmp(key, "DisplayLevel") == 0) m_logDisplayLevel = (unsigned int)::atoi(value); - } else if (section == SECTION_MQTT) { + } else if (section == SECTION::MQTT) { if (::strcmp(key, "Address") == 0) m_mqttAddress = value; else if (::strcmp(key, "Port") == 0) @@ -170,7 +167,7 @@ bool CConf::read() m_mqttKeepalive = (unsigned int)::atoi(value); else if (::strcmp(key, "Name") == 0) m_mqttName = value; - } else if (section == SECTION_DAPNET) { + } else if (section == SECTION::DAPNET) { if (::strcmp(key, "Address") == 0) m_dapnetAddress = value; else if (::strcmp(key, "Port") == 0) @@ -180,8 +177,7 @@ bool CConf::read() if (!::isspace(value[i])) m_dapnetAuthKey.insert(m_dapnetAuthKey.end(), 1, value[i]); } - } - else if (::strcmp(key, "Debug") == 0) + } else if (::strcmp(key, "Debug") == 0) m_dapnetDebug = ::atoi(value) == 1; } } diff --git a/DAPNETGateway.cpp b/DAPNETGateway.cpp index a744a91..b0b5dea 100644 --- a/DAPNETGateway.cpp +++ b/DAPNETGateway.cpp @@ -1,5 +1,9 @@ /* +<<<<<<< HEAD * Copyright (C) 2018,2020,2023,2024 by Jonathan Naylor G4KLX +======= +* Copyright (C) 2018,2020,2024,2025 by Jonathan Naylor G4KLX +>>>>>>> master * * 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 @@ -153,11 +157,11 @@ int main(int argc, char** argv) CDAPNETGateway::CDAPNETGateway(const std::string& configFile) : m_conf(configFile), -m_dapnetNetwork(NULL), -m_pocsagNetwork(NULL), +m_dapnetNetwork(nullptr), +m_pocsagNetwork(nullptr), m_queue(), m_slotTimer(), -m_schedule(NULL), +m_schedule(nullptr), m_allSlots(false), m_currentSlot(0U), m_sentCodewords(0U), @@ -215,7 +219,7 @@ int CDAPNETGateway::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; } @@ -362,7 +366,7 @@ int CDAPNETGateway::run() recover(); CPOCSAGMessage* message = m_dapnetNetwork->readMessage(); - if (message != NULL) { + if (message != nullptr) { bool found = true; bool blackListRIC = false; bool blacklistRegexmatch = false; @@ -430,7 +434,7 @@ int CDAPNETGateway::run() if (slot != m_currentSlot) { // LogDebug("Start of slot %u", slot); m_currentSlot = slot; - if (m_schedule == NULL || m_currentSlot == 0U) + if (m_schedule == nullptr || m_currentSlot == 0U) loadSchedule(); m_sentCodewords = 0U; m_slotTimer.start(); @@ -460,7 +464,7 @@ void CDAPNETGateway::sendMessages() return; // Do we have a schedule? - if (m_schedule == NULL) + if (m_schedule == nullptr) return; // Check to see if we're allowed to send within a slot. @@ -472,7 +476,7 @@ void CDAPNETGateway::sendMessages() return; CPOCSAGMessage* message = m_queue.back(); - assert(message != NULL); + assert(message != nullptr); // Special case, only test if slots are being used. if (m_allSlots) { @@ -536,7 +540,7 @@ bool CDAPNETGateway::isTimeMessage(const CPOCSAGMessage* message) const unsigned int CDAPNETGateway::calculateCodewords(const CPOCSAGMessage* message) const { - assert(message != NULL); + assert(message != nullptr); unsigned int len = 0U; switch (message->m_functional) { @@ -565,7 +569,7 @@ unsigned int CDAPNETGateway::calculateCodewords(const CPOCSAGMessage* message) c void CDAPNETGateway::loadSchedule() { bool* schedule = m_dapnetNetwork->readSchedule(); - if (schedule == NULL) + if (schedule == nullptr) return; delete[] m_schedule; @@ -591,7 +595,7 @@ void CDAPNETGateway::loadSchedule() bool CDAPNETGateway::sendMessage(CPOCSAGMessage* message) const { - assert(message != NULL); + assert(message != nullptr); bool ret = isTimeMessage(message); if (ret && message->m_timeQueued.elapsed() >= MAX_TIME_TO_HOLD_TIME_MESSAGES) { diff --git a/DAPNETGateway.vcxproj b/DAPNETGateway.vcxproj index 0a39333..4388a7d 100644 --- a/DAPNETGateway.vcxproj +++ b/DAPNETGateway.vcxproj @@ -23,6 +23,7 @@ + @@ -39,6 +40,7 @@ + @@ -121,11 +123,13 @@ true HAVE_LOG_H;_CRT_SECURE_NO_WARNINGS true + C:\Program Files\mosquitto\devel;C:\Program Files Console true - ws2_32.lib;%(AdditionalDependencies) + ws2_32.lib;mosquitto.lib;%(AdditionalDependencies) + C:\Program Files\mosquitto\devel prebuild.cmd @@ -139,11 +143,13 @@ true HAVE_LOG_H;_CRT_SECURE_NO_WARNINGS true + C:\Program Files\mosquitto\devel;C:\Program Files Console true - ws2_32.lib;%(AdditionalDependencies) + ws2_32.lib;mosquitto.lib;%(AdditionalDependencies) + C:\Program Files\mosquitto\devel prebuild.cmd @@ -159,13 +165,15 @@ true HAVE_LOG_H;_CRT_SECURE_NO_WARNINGS true + C:\Program Files\mosquitto\devel;C:\Program Files Console true true true - ws2_32.lib;%(AdditionalDependencies) + ws2_32.lib;mosquitto.lib;%(AdditionalDependencies) + C:\Program Files\mosquitto\devel prebuild.cmd @@ -181,13 +189,15 @@ true HAVE_LOG_H;_CRT_SECURE_NO_WARNINGS true + C:\Program Files\mosquitto\devel;C:\Program Files Console true true true - ws2_32.lib;%(AdditionalDependencies) + ws2_32.lib;mosquitto.lib;%(AdditionalDependencies) + C:\Program Files\mosquitto\devel prebuild.cmd diff --git a/DAPNETGateway.vcxproj.filters b/DAPNETGateway.vcxproj.filters index 442cacc..e3841f4 100644 --- a/DAPNETGateway.vcxproj.filters +++ b/DAPNETGateway.vcxproj.filters @@ -53,6 +53,9 @@ Header Files + + Header Files + @@ -94,5 +97,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/DAPNETNetwork.cpp b/DAPNETNetwork.cpp index 7b5fb7d..de535ca 100644 --- a/DAPNETNetwork.cpp +++ b/DAPNETNetwork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -27,6 +27,8 @@ #include #include +const unsigned int BACKOFF[] = { 2000U, 4000U, 8000U, 10000U, 20000U, 60000U, 120000U, 240000U, 480000U, 600000U }; + const unsigned int BUFFER_LENGTH = 200U; CDAPNETNetwork::CDAPNETNetwork(const std::string& address, unsigned short port, const std::string& callsign, const std::string& authKey, const char* version, bool loggedIn, int failCount, bool debug) : @@ -37,12 +39,12 @@ m_version(version), m_loggedIn(false), m_failCount(failCount), m_debug(debug), -m_message(NULL), -m_schedule(NULL) +m_message(nullptr), +m_schedule(nullptr) { assert(!callsign.empty()); assert(!authKey.empty()); - assert(version != NULL); + assert(version != nullptr); } CDAPNETNetwork::~CDAPNETNetwork() @@ -101,7 +103,7 @@ bool CDAPNETNetwork::read() } // Time synchronisation char* p = ::strchr((char*)buffer, '\n'); - if (p != NULL) + if (p != nullptr) ::strcpy(p, ":0000\r\n"); else ::strcat((char*)buffer, ":0000\r\n"); @@ -135,19 +137,19 @@ bool* CDAPNETNetwork::readSchedule() { bool* schedule = m_schedule; - m_schedule = NULL; + m_schedule = nullptr; return schedule; } CPOCSAGMessage* CDAPNETNetwork::readMessage() { - if (m_message == NULL) - return NULL; + if (m_message == nullptr) + return nullptr; CPOCSAGMessage* message = m_message; - m_message = NULL; + m_message = nullptr; return message; } @@ -161,9 +163,9 @@ void CDAPNETNetwork::close() bool CDAPNETNetwork::write(unsigned char* data) { - assert(data != NULL); + assert(data != nullptr); - unsigned int length = ::strlen((char*)data); + unsigned int length = (unsigned int)::strlen((char*)data); if (m_debug) CUtils::dump(1U, "DAPNET Data Transmitted", data, length); @@ -177,17 +179,17 @@ bool CDAPNETNetwork::write(unsigned char* data) bool CDAPNETNetwork::parseMessage(unsigned char* buffer, unsigned int length) { - assert(buffer != NULL); + assert(buffer != nullptr); - unsigned int id = ::strtoul((char*)buffer + 1U, NULL, 16); + unsigned int id = ::strtoul((char*)buffer + 1U, nullptr, 16); char* p1 = ::strtok((char*)buffer + 4U, ":\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* p2 = ::strtok(nullptr, ":\r\n"); + char* p3 = ::strtok(nullptr, ":\r\n"); + char* p4 = ::strtok(nullptr, ":\r\n"); + char* p5 = ::strtok(nullptr, "\r\n"); - if (p1 == NULL || p2 == NULL || p3 == NULL || p4 == NULL || p5 == NULL) { + if (p1 == nullptr || p2 == nullptr || p3 == nullptr || p4 == nullptr || p5 == nullptr) { CUtils::dump(3U, "Received a malformed message from DAPNET", buffer, length); id = (id + 1U) % 256UL; @@ -196,11 +198,11 @@ bool CDAPNETNetwork::parseMessage(unsigned char* buffer, unsigned int length) ::snprintf(reply, 20U, "#%02X -\r\n", id); return write((unsigned char*)reply); } else { - unsigned int type = ::strtoul(p1, NULL, 10); - unsigned int addr = ::strtoul(p3, NULL, 16); - unsigned int func = ::strtoul(p4, NULL, 10); + unsigned int type = ::strtoul(p1, nullptr, 10); + unsigned int addr = ::strtoul(p3, nullptr, 16); + unsigned int func = ::strtoul(p4, nullptr, 10); - m_message = new CPOCSAGMessage(type, addr, func, (unsigned char*)p5, ::strlen(p5)); + m_message = new CPOCSAGMessage(type, addr, func, (unsigned char*)p5, (unsigned int)::strlen(p5)); id = (id + 1U) % 256UL; @@ -212,10 +214,10 @@ bool CDAPNETNetwork::parseMessage(unsigned char* buffer, unsigned int length) bool CDAPNETNetwork::parseSchedule(unsigned char* data) { - assert(data != NULL); + assert(data != nullptr); char* p = ::strtok((char*)data + 2U, "\r\n"); - assert(p != NULL); + assert(p != nullptr); LogMessage("Schedule information received: %s", p); @@ -225,37 +227,37 @@ bool CDAPNETNetwork::parseSchedule(unsigned char* data) for (unsigned int i = 0U; i < 16U; i++) m_schedule[i] = false; - if (::strchr(p, '0') != NULL) + if (::strchr(p, '0') != nullptr) m_schedule[0U] = true; - if (::strchr(p, '1') != NULL) + if (::strchr(p, '1') != nullptr) m_schedule[1U] = true; - if (::strchr(p, '2') != NULL) + if (::strchr(p, '2') != nullptr) m_schedule[2U] = true; - if (::strchr(p, '3') != NULL) + if (::strchr(p, '3') != nullptr) m_schedule[3U] = true; - if (::strchr(p, '4') != NULL) + if (::strchr(p, '4') != nullptr) m_schedule[4U] = true; - if (::strchr(p, '5') != NULL) + if (::strchr(p, '5') != nullptr) m_schedule[5U] = true; - if (::strchr(p, '6') != NULL) + if (::strchr(p, '6') != nullptr) m_schedule[6U] = true; - if (::strchr(p, '7') != NULL) + if (::strchr(p, '7') != nullptr) m_schedule[7U] = true; - if (::strchr(p, '8') != NULL) + if (::strchr(p, '8') != nullptr) m_schedule[8U] = true; - if (::strchr(p, '9') != NULL) + if (::strchr(p, '9') != nullptr) m_schedule[9U] = true; - if (::strchr(p, 'A') != NULL) + if (::strchr(p, 'A') != nullptr) m_schedule[10U] = true; - if (::strchr(p, 'B') != NULL) + if (::strchr(p, 'B') != nullptr) m_schedule[11U] = true; - if (::strchr(p, 'C') != NULL) + if (::strchr(p, 'C') != nullptr) m_schedule[12U] = true; - if (::strchr(p, 'D') != NULL) + if (::strchr(p, 'D') != nullptr) m_schedule[13U] = true; - if (::strchr(p, 'E') != NULL) + if (::strchr(p, 'E') != nullptr) m_schedule[14U] = true; - if (::strchr(p, 'F') != NULL) + if (::strchr(p, 'F') != nullptr) m_schedule[15U] = true; return write((unsigned char*)"+\r\n"); @@ -263,16 +265,14 @@ bool CDAPNETNetwork::parseSchedule(unsigned char* data) bool CDAPNETNetwork::parseFailedLogin(unsigned char* data) { - assert(data != NULL); + assert(data != nullptr); char* p = ::strtok((char*)data + 2U, "\r\n"); - assert(p != NULL); - - const unsigned int backoff[] = {2000u, 4000u, 8000u, 10000u, 20000u, 60000u, 120000u, 240000u, 480000u, 600000u}; + assert(p != nullptr); LogMessage("Login failed: %s", p); - CThread::sleep(backoff[m_failCount]); + CThread::sleep(BACKOFF[m_failCount]); if (m_failCount < 9) m_failCount++; diff --git a/Log.cpp b/Log.cpp index 4537544..222d18e 100644 --- a/Log.cpp +++ b/Log.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2020,2022,2023 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2020,2022,2023,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,7 +33,7 @@ #include #include -CMQTTConnection* m_mqtt = NULL; +CMQTTConnection* m_mqtt = nullptr; static unsigned int m_mqttLevel = 2U; @@ -49,16 +49,16 @@ void LogInitialise(unsigned int displayLevel, unsigned int mqttLevel) void LogFinalise() { - if (m_mqtt != NULL) { + if (m_mqtt != nullptr) { m_mqtt->close(); delete m_mqtt; - m_mqtt = NULL; + m_mqtt = nullptr; } } void Log(unsigned int level, const char* fmt, ...) { - assert(fmt != NULL); + assert(fmt != nullptr); char buffer[501U]; #if defined(_WIN32) || defined(_WIN64) @@ -68,7 +68,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); @@ -78,11 +78,11 @@ 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); - if (m_mqtt != NULL && level >= m_mqttLevel && m_mqttLevel != 0U) + if (m_mqtt != nullptr && level >= m_mqttLevel && m_mqttLevel != 0U) m_mqtt->publish("log", buffer); if (level >= m_displayLevel && m_displayLevel != 0U) { @@ -96,7 +96,7 @@ void Log(unsigned int level, const char* fmt, ...) void WriteJSON(const std::string& topLevel, nlohmann::json& json) { - if (m_mqtt != NULL) { + if (m_mqtt != nullptr) { nlohmann::json top; top[topLevel] = json; diff --git a/MQTTConnection.cpp b/MQTTConnection.cpp index fa951e5..333fbbe 100644 --- a/MQTTConnection.cpp +++ b/MQTTConnection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022,2023 by Jonathan Naylor G4KLX + * Copyright (C) 2022,2023,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,7 +21,7 @@ #include #include #include - +#include CMQTTConnection::CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector>& subs, unsigned int keepalive, MQTT_QOS qos) : m_host(host), @@ -30,7 +30,7 @@ m_name(name), m_subs(subs), m_keepalive(keepalive), m_qos(qos), -m_mosq(NULL), +m_mosq(nullptr), m_connected(false) { assert(!host.empty()); @@ -48,8 +48,13 @@ CMQTTConnection::~CMQTTConnection() bool CMQTTConnection::open() { - m_mosq = ::mosquitto_new(m_name.c_str(), true, this); - if (m_mosq == NULL){ + char name[50U]; + ::sprintf(name, "DAPNETGateway.%ld", ::time(nullptr)); + + ::fprintf(stdout, "DAPNETGateway (%s) connecting to MQTT as %s\n", m_name.c_str(), name); + + m_mosq = ::mosquitto_new(name, true, this); + if (m_mosq == nullptr){ ::fprintf(stderr, "MQTT Error newing: Out of memory.\n"); return false; } @@ -62,7 +67,7 @@ bool CMQTTConnection::open() int rc = ::mosquitto_connect(m_mosq, m_host.c_str(), m_port, m_keepalive); if (rc != MOSQ_ERR_SUCCESS) { ::mosquitto_destroy(m_mosq); - m_mosq = NULL; + m_mosq = nullptr; ::fprintf(stderr, "MQTT Error connecting: %s\n", ::mosquitto_strerror(rc)); return false; } @@ -71,7 +76,7 @@ bool CMQTTConnection::open() if (rc != MOSQ_ERR_SUCCESS) { ::mosquitto_disconnect(m_mosq); ::mosquitto_destroy(m_mosq); - m_mosq = NULL; + m_mosq = nullptr; ::fprintf(stderr, "MQTT Error loop starting: %s\n", ::mosquitto_strerror(rc)); return false; } @@ -81,38 +86,38 @@ bool CMQTTConnection::open() bool CMQTTConnection::publish(const char* topic, const char* text) { - assert(topic != NULL); - assert(text != NULL); + assert(topic != nullptr); + assert(text != nullptr); - return publish(topic, (unsigned char*)text, ::strlen(text)); + return publish(topic, (unsigned char*)text, (unsigned int)::strlen(text)); } bool CMQTTConnection::publish(const char* topic, const std::string& text) { - assert(topic != NULL); + assert(topic != nullptr); - return publish(topic, (unsigned char*)text.c_str(), text.size()); + return publish(topic, (unsigned char*)text.c_str(), (unsigned int)text.size()); } bool CMQTTConnection::publish(const char* topic, const unsigned char* data, unsigned int len) { - assert(topic != NULL); - assert(data != NULL); + assert(topic != nullptr); + assert(data != nullptr); if (!m_connected) return false; - if (::strchr(topic, '/') == NULL) { + if (::strchr(topic, '/') == nullptr) { char topicEx[100U]; ::sprintf(topicEx, "%s/%s", m_name.c_str(), topic); - int rc = ::mosquitto_publish(m_mosq, NULL, topicEx, len, data, static_cast(m_qos), false); + int rc = ::mosquitto_publish(m_mosq, nullptr, topicEx, len, data, static_cast(m_qos), false); if (rc != MOSQ_ERR_SUCCESS) { ::fprintf(stderr, "MQTT Error publishing: %s\n", ::mosquitto_strerror(rc)); return false; } } else { - int rc = ::mosquitto_publish(m_mosq, NULL, topic, len, data, static_cast(m_qos), false); + int rc = ::mosquitto_publish(m_mosq, nullptr, topic, len, data, static_cast(m_qos), false); if (rc != MOSQ_ERR_SUCCESS) { ::fprintf(stderr, "MQTT Error publishing: %s\n", ::mosquitto_strerror(rc)); return false; @@ -124,17 +129,17 @@ bool CMQTTConnection::publish(const char* topic, const unsigned char* data, unsi void CMQTTConnection::close() { - if (m_mosq != NULL) { + if (m_mosq != nullptr) { ::mosquitto_disconnect(m_mosq); ::mosquitto_destroy(m_mosq); - m_mosq = NULL; + m_mosq = nullptr; } } void CMQTTConnection::onConnect(mosquitto* mosq, void* obj, int rc) { - assert(mosq != NULL); - assert(obj != NULL); + assert(mosq != nullptr); + assert(obj != nullptr); ::fprintf(stdout, "MQTT: on_connect: %s\n", ::mosquitto_connack_string(rc)); if (rc != 0) { @@ -152,13 +157,13 @@ void CMQTTConnection::onConnect(mosquitto* mosq, void* obj, int rc) char topicEx[100U]; ::sprintf(topicEx, "%s/%s", p->m_name.c_str(), topic.c_str()); - rc = ::mosquitto_subscribe(mosq, NULL, topicEx, static_cast(p->m_qos)); + rc = ::mosquitto_subscribe(mosq, nullptr, topicEx, static_cast(p->m_qos)); if (rc != MOSQ_ERR_SUCCESS) { ::fprintf(stderr, "MQTT: error subscribing to %s - %s\n", topicEx, ::mosquitto_strerror(rc)); ::mosquitto_disconnect(mosq); } } else { - rc = ::mosquitto_subscribe(mosq, NULL, topic.c_str(), static_cast(p->m_qos)); + rc = ::mosquitto_subscribe(mosq, nullptr, topic.c_str(), static_cast(p->m_qos)); if (rc != MOSQ_ERR_SUCCESS) { ::fprintf(stderr, "MQTT: error subscribing to %s - %s\n", topic.c_str(), ::mosquitto_strerror(rc)); ::mosquitto_disconnect(mosq); @@ -169,9 +174,9 @@ void CMQTTConnection::onConnect(mosquitto* mosq, void* obj, int rc) void CMQTTConnection::onSubscribe(mosquitto* mosq, void* obj, int mid, int qosCount, const int* grantedQOS) { - assert(mosq != NULL); - assert(obj != NULL); - assert(grantedQOS != NULL); + assert(mosq != nullptr); + assert(obj != nullptr); + assert(grantedQOS != nullptr); for (int i = 0; i < qosCount; i++) ::fprintf(stdout, "MQTT: on_subscribe: %d:%d\n", i, grantedQOS[i]); @@ -179,9 +184,9 @@ void CMQTTConnection::onSubscribe(mosquitto* mosq, void* obj, int mid, int qosCo void CMQTTConnection::onMessage(mosquitto* mosq, void* obj, const mosquitto_message* message) { - assert(mosq != NULL); - assert(obj != NULL); - assert(message != NULL); + assert(mosq != nullptr); + assert(obj != nullptr); + assert(message != nullptr); CMQTTConnection* p = static_cast(obj); @@ -200,8 +205,8 @@ void CMQTTConnection::onMessage(mosquitto* mosq, void* obj, const mosquitto_mess void CMQTTConnection::onDisconnect(mosquitto* mosq, void* obj, int rc) { - assert(mosq != NULL); - assert(obj != NULL); + assert(mosq != nullptr); + assert(obj != nullptr); ::fprintf(stdout, "MQTT: on_disconnect: %s\n", ::mosquitto_reason_string(rc)); diff --git a/MQTTConnection.h b/MQTTConnection.h index 8fc98ce..3d9ccfb 100644 --- a/MQTTConnection.h +++ b/MQTTConnection.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022,2023 by Jonathan Naylor G4KLX + * Copyright (C) 2022,2023,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 @@ -24,15 +24,15 @@ #include #include -enum MQTT_QOS { - MQTT_QOS_AT_MODE_ONCE = 0U, - MQTT_QOS_AT_LEAST_ONCE = 1U, - MQTT_QOS_EXACTLY_ONCE = 2U +enum class MQTT_QOS : int { + AT_MODE_ONCE = 0U, + AT_LEAST_ONCE = 1U, + EXACTLY_ONCE = 2U }; class CMQTTConnection { public: - CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector>& subs, unsigned int keepalive, MQTT_QOS qos = MQTT_QOS_EXACTLY_ONCE); + CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector>& subs, unsigned int keepalive, MQTT_QOS qos = MQTT_QOS::EXACTLY_ONCE); ~CMQTTConnection(); bool open(); diff --git a/POCSAGMessage.cpp b/POCSAGMessage.cpp index ff53c18..75b2291 100644 --- a/POCSAGMessage.cpp +++ b/POCSAGMessage.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2018 by Jonathan Naylor G4KLX +* Copyright (C) 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 @@ -26,12 +26,12 @@ CPOCSAGMessage::CPOCSAGMessage(unsigned char type, unsigned int ric, unsigned ch m_type(type), m_ric(ric), m_functional(functional), -m_message(NULL), +m_message(nullptr), m_length(length), m_timeQueued() { assert(functional < 4U); - assert(message != NULL); + assert(message != nullptr); assert(length > 0U); m_message = new unsigned char[length + 1]; diff --git a/POCSAGNetwork.cpp b/POCSAGNetwork.cpp index 69c1d73..a6ad050 100644 --- a/POCSAGNetwork.cpp +++ b/POCSAGNetwork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -56,7 +56,7 @@ bool CPOCSAGNetwork::open() bool CPOCSAGNetwork::write(CPOCSAGMessage* message) { - assert(message != NULL); + assert(message != nullptr); unsigned char data[200U]; data[0U] = 'P'; @@ -82,7 +82,7 @@ bool CPOCSAGNetwork::write(CPOCSAGMessage* message) unsigned int CPOCSAGNetwork::read(unsigned char* data) { - assert(data != NULL); + assert(data != nullptr); sockaddr_storage address; unsigned int addrLen; diff --git a/REGEX.cpp b/REGEX.cpp index 0caaba5..2506ca5 100644 --- a/REGEX.cpp +++ b/REGEX.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017,2025 by Jonathan Naylor G4KLX * * Contributed by Simon G7RZU * @@ -46,16 +46,16 @@ bool CREGEX::load() FILE* fp = ::fopen(m_regexFile.c_str(), "rt"); - if (fp != NULL) { + if (fp != nullptr) { char buffer[100U]; std::regex regex; - while (::fgets(buffer, 100U, fp) != NULL) { + while (::fgets(buffer, 100U, fp) != nullptr) { if (buffer[0U] == '#') continue; const char* regexStr = ::strtok(buffer, "\r\n"); - if (regexStr != NULL) { + if (regexStr != nullptr) { try { regex = std::regex(regexStr); } diff --git a/StopWatch.cpp b/StopWatch.cpp index 481241b..3d59e12 100644 --- a/StopWatch.cpp +++ b/StopWatch.cpp @@ -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; } diff --git a/TCPSocket.cpp b/TCPSocket.cpp index 25ce8d6..b971629 100644 --- a/TCPSocket.cpp +++ b/TCPSocket.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013,2016,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2010-2013,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 @@ -33,7 +33,11 @@ typedef int ssize_t; CTCPSocket::CTCPSocket(const std::string& address, unsigned int port) : m_address(address), m_port(port), +#if defined(_WIN32) || defined(_WIN64) +m_fd(INVALID_SOCKET) +#else m_fd(-1) +#endif { assert(!address.empty()); assert(port > 0U); @@ -55,8 +59,13 @@ CTCPSocket::~CTCPSocket() bool CTCPSocket::open() { +#if defined(_WIN32) || defined(_WIN64) + if (m_fd != INVALID_SOCKET) + return true; +#else if (m_fd != -1) return true; +#endif if (m_address.empty() || m_port == 0U) return false; @@ -114,9 +123,13 @@ bool CTCPSocket::open() int CTCPSocket::read(unsigned char* buffer, unsigned int length, unsigned int secs, unsigned int msecs) { - assert(buffer != NULL); + assert(buffer != nullptr); assert(length > 0U); +#if defined(_WIN32) || defined(_WIN64) + assert(m_fd != INVALID_SOCKET); +#else assert(m_fd != -1); +#endif // Check that the recv() won't block fd_set readFds; @@ -132,7 +145,7 @@ int CTCPSocket::read(unsigned char* buffer, unsigned int length, unsigned int se tv.tv_sec = secs; tv.tv_usec = msecs * 1000; - int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv); + int ret = ::select(int(m_fd) + 1, &readFds, nullptr, nullptr, &tv); if (ret < 0) { #if defined(_WIN32) || defined(_WIN64) LogError("Error returned from TCP client select, err=%d", ::GetLastError()); @@ -191,9 +204,13 @@ int CTCPSocket::readLine(std::string& line, unsigned int secs) bool CTCPSocket::write(const unsigned char* buffer, unsigned int length) { - assert(buffer != NULL); + assert(buffer != nullptr); assert(length > 0U); +#if defined(_WIN32) || defined(_WIN64) + assert(m_fd != INVALID_SOCKET); +#else assert(m_fd != -1); +#endif ssize_t ret = ::send(m_fd, (char *)buffer, length, 0); if (ret != ssize_t(length)) { @@ -227,12 +244,15 @@ bool CTCPSocket::writeLine(const std::string& line) void CTCPSocket::close() { - if (m_fd != -1) { #if defined(_WIN32) || defined(_WIN64) + if (m_fd != INVALID_SOCKET) { ::closesocket(m_fd); + m_fd = INVALID_SOCKET; + } #else + if (m_fd != -1) { ::close(m_fd); -#endif m_fd = -1; } +#endif } diff --git a/TCPSocket.h b/TCPSocket.h index 7a20eb3..0465715 100644 --- a/TCPSocket.h +++ b/TCPSocket.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010,2011,2012,2013,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2010,2011,2012,2013,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 @@ -53,7 +53,11 @@ public: private: std::string m_address; unsigned short m_port; +#if defined(_WIN32) || defined(_WIN64) + SOCKET m_fd; +#else int m_fd; +#endif }; #endif diff --git a/Thread.cpp b/Thread.cpp index 6f76f5b..86b8967 100644 --- a/Thread.cpp +++ b/Thread.cpp @@ -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 diff --git a/UDPSocket.cpp b/UDPSocket.cpp index 6981e29..bb00d1d 100644 --- a/UDPSocket.cpp +++ b/UDPSocket.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2016,2020,2024 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 @@ -86,7 +86,7 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd /* 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() ? nullptr : 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)); @@ -97,7 +97,7 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd return err; } - ::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen); + ::memcpy(&addr, res->ai_addr, address_length = (unsigned int)res->ai_addrlen); ::freeaddrinfo(res); @@ -109,7 +109,7 @@ 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; @@ -124,7 +124,7 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad 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; @@ -219,7 +219,7 @@ bool CUDPSocket::open() int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength) { - assert(buffer != NULL); + assert(buffer != nullptr); assert(length > 0U); assert(m_fd >= 0); @@ -280,7 +280,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag 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); assert(m_fd >= 0); diff --git a/UDPSocket.h b/UDPSocket.h index 75228a3..2340d35 100644 --- a/UDPSocket.h +++ b/UDPSocket.h @@ -35,9 +35,9 @@ #include #endif -enum IPMATCHTYPE { - IMT_ADDRESS_AND_PORT, - IMT_ADDRESS_ONLY +enum class IPMATCHTYPE { + ADDRESS_AND_PORT, + ADDRESS_ONLY }; class CUDPSocket { @@ -60,7 +60,7 @@ public: 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); diff --git a/Utils.cpp b/Utils.cpp index bbecbfd..a71832e 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2014,2015,2016,2023 Jonathan Naylor, G4KLX + * Copyright (C) 2009,2014,2015,2016,2023,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 @@ -26,14 +26,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()); @@ -88,7 +88,7 @@ std::string CUtils::createTimestamp() ::sprintf(buffer, "%04u-%02u-%02u %02u:%02u:%02u.%03u", 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); diff --git a/Version.h b/Version.h index 9612631..3752c6e 100644 --- a/Version.h +++ b/Version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018,2020,2023,2024 by Jonathan Naylor G4KLX + * Copyright (C) 2018,2020,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 = "20240831"; +const char* VERSION = "20250318"; #endif