mirror of
https://github.com/g4klx/DMRGateway
synced 2025-12-23 14:56:11 +08:00
Update the C++ version and other changes.
This commit is contained in:
78
Conf.cpp
78
Conf.cpp
@@ -26,23 +26,23 @@
|
|||||||
|
|
||||||
const int BUFFER_SIZE = 500;
|
const int BUFFER_SIZE = 500;
|
||||||
|
|
||||||
enum SECTION {
|
enum class SECTION {
|
||||||
SECTION_NONE,
|
NONE,
|
||||||
SECTION_GENERAL,
|
GENERAL,
|
||||||
SECTION_LOG,
|
LOG,
|
||||||
SECTION_VOICE,
|
VOICE,
|
||||||
SECTION_INFO,
|
INFO,
|
||||||
SECTION_DMR_NETWORK_1,
|
DMR_NETWORK_1,
|
||||||
SECTION_DMR_NETWORK_2,
|
DMR_NETWORK_2,
|
||||||
SECTION_DMR_NETWORK_3,
|
DMR_NETWORK_3,
|
||||||
SECTION_DMR_NETWORK_4,
|
DMR_NETWORK_4,
|
||||||
SECTION_DMR_NETWORK_5,
|
DMR_NETWORK_5,
|
||||||
SECTION_XLX_NETWORK,
|
XLX_NETWORK,
|
||||||
SECTION_GPSD,
|
GPSD,
|
||||||
SECTION_APRS,
|
APRS,
|
||||||
SECTION_MQTT,
|
MQTT,
|
||||||
SECTION_DYNAMIC_TG_CONTROL,
|
DYNAMIC_TG_CONTROL,
|
||||||
SECTION_REMOTE_COMMANDS
|
REMOTE_COMMANDS
|
||||||
};
|
};
|
||||||
|
|
||||||
CConf::CConf(const std::string& file) :
|
CConf::CConf(const std::string& file) :
|
||||||
@@ -209,37 +209,37 @@ bool CConf::read()
|
|||||||
|
|
||||||
if (buffer[0U] == '[') {
|
if (buffer[0U] == '[') {
|
||||||
if (::strncmp(buffer, "[General]", 9U) == 0)
|
if (::strncmp(buffer, "[General]", 9U) == 0)
|
||||||
section = SECTION_GENERAL;
|
section = SECTION::GENERAL;
|
||||||
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
||||||
section = SECTION_LOG;
|
section = SECTION::LOG;
|
||||||
else if (::strncmp(buffer, "[Voice]", 7U) == 0)
|
else if (::strncmp(buffer, "[Voice]", 7U) == 0)
|
||||||
section = SECTION_VOICE;
|
section = SECTION::VOICE;
|
||||||
else if (::strncmp(buffer, "[Info]", 6U) == 0)
|
else if (::strncmp(buffer, "[Info]", 6U) == 0)
|
||||||
section = SECTION_INFO;
|
section = SECTION::INFO;
|
||||||
else if (::strncmp(buffer, "[XLX Network]", 13U) == 0)
|
else if (::strncmp(buffer, "[XLX Network]", 13U) == 0)
|
||||||
section = SECTION_XLX_NETWORK;
|
section = SECTION::XLX_NETWORK;
|
||||||
else if (::strncmp(buffer, "[DMR Network 1]", 15U) == 0)
|
else if (::strncmp(buffer, "[DMR Network 1]", 15U) == 0)
|
||||||
section = SECTION_DMR_NETWORK_1;
|
section = SECTION::DMR_NETWORK_1;
|
||||||
else if (::strncmp(buffer, "[DMR Network 2]", 15U) == 0)
|
else if (::strncmp(buffer, "[DMR Network 2]", 15U) == 0)
|
||||||
section = SECTION_DMR_NETWORK_2;
|
section = SECTION::DMR_NETWORK_2;
|
||||||
else if (::strncmp(buffer, "[DMR Network 3]", 15U) == 0)
|
else if (::strncmp(buffer, "[DMR Network 3]", 15U) == 0)
|
||||||
section = SECTION_DMR_NETWORK_3;
|
section = SECTION::DMR_NETWORK_3;
|
||||||
else if (::strncmp(buffer, "[DMR Network 4]", 15U) == 0)
|
else if (::strncmp(buffer, "[DMR Network 4]", 15U) == 0)
|
||||||
section = SECTION_DMR_NETWORK_4;
|
section = SECTION::DMR_NETWORK_4;
|
||||||
else if (::strncmp(buffer, "[DMR Network 5]", 15U) == 0)
|
else if (::strncmp(buffer, "[DMR Network 5]", 15U) == 0)
|
||||||
section = SECTION_DMR_NETWORK_5;
|
section = SECTION::DMR_NETWORK_5;
|
||||||
else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
|
else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
|
||||||
section = SECTION_GPSD;
|
section = SECTION::GPSD;
|
||||||
else if (::strncmp(buffer, "[APRS]", 6U) == 0)
|
else if (::strncmp(buffer, "[APRS]", 6U) == 0)
|
||||||
section = SECTION_APRS;
|
section = SECTION::APRS;
|
||||||
else if (::strncmp(buffer, "[MQTT]", 6U) == 0)
|
else if (::strncmp(buffer, "[MQTT]", 6U) == 0)
|
||||||
section = SECTION_MQTT;
|
section = SECTION::MQTT;
|
||||||
else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0)
|
else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0)
|
||||||
section = SECTION_DYNAMIC_TG_CONTROL;
|
section = SECTION::DYNAMIC_TG_CONTROL;
|
||||||
else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0)
|
else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0)
|
||||||
section = SECTION_REMOTE_COMMANDS;
|
section = SECTION::REMOTE_COMMANDS;
|
||||||
else
|
else
|
||||||
section = SECTION_NONE;
|
section = SECTION::NONE;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -290,12 +290,12 @@ bool CConf::read()
|
|||||||
m_ruleTrace = ::atoi(value) == 1;
|
m_ruleTrace = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_debug = ::atoi(value) == 1;
|
m_debug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_LOG) {
|
} else if (section == SECTION::LOG) {
|
||||||
if (::strcmp(key, "MQTTLevel") == 0)
|
if (::strcmp(key, "MQTTLevel") == 0)
|
||||||
m_logMQTTLevel = (unsigned int)::atoi(value);
|
m_logMQTTLevel = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "DisplayLevel") == 0)
|
else if (::strcmp(key, "DisplayLevel") == 0)
|
||||||
m_logDisplayLevel = (unsigned int)::atoi(value);
|
m_logDisplayLevel = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_VOICE) {
|
} else if (section == SECTION::VOICE) {
|
||||||
if (::strcmp(key, "Enabled") == 0)
|
if (::strcmp(key, "Enabled") == 0)
|
||||||
m_voiceEnabled = ::atoi(value) == 1;
|
m_voiceEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Language") == 0)
|
else if (::strcmp(key, "Language") == 0)
|
||||||
@@ -354,7 +354,7 @@ bool CConf::read()
|
|||||||
m_xlxNetworkUserControl = ::atoi(value) ==1;
|
m_xlxNetworkUserControl = ::atoi(value) ==1;
|
||||||
else if (::strcmp(key, "Module") == 0)
|
else if (::strcmp(key, "Module") == 0)
|
||||||
m_xlxNetworkModule = ::toupper(value[0]);
|
m_xlxNetworkModule = ::toupper(value[0]);
|
||||||
} else if (section == SECTION_DMR_NETWORK_1) {
|
} else if (section == SECTION::DMR_NETWORK_1) {
|
||||||
if (::strcmp(key, "Enabled") == 0)
|
if (::strcmp(key, "Enabled") == 0)
|
||||||
m_dmrNetwork1Enabled = ::atoi(value) == 1;
|
m_dmrNetwork1Enabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Name") == 0)
|
else if (::strcmp(key, "Name") == 0)
|
||||||
@@ -980,7 +980,7 @@ bool CConf::read()
|
|||||||
m_aprsDescription = value;
|
m_aprsDescription = value;
|
||||||
else if (::strcmp(key, "Symbol") == 0)
|
else if (::strcmp(key, "Symbol") == 0)
|
||||||
m_aprsSymbol = value;
|
m_aprsSymbol = value;
|
||||||
} else if (section == SECTION_MQTT) {
|
} else if (section == SECTION::MQTT) {
|
||||||
if (::strcmp(key, "Address") == 0)
|
if (::strcmp(key, "Address") == 0)
|
||||||
m_mqttAddress = value;
|
m_mqttAddress = value;
|
||||||
else if (::strcmp(key, "Port") == 0)
|
else if (::strcmp(key, "Port") == 0)
|
||||||
@@ -989,10 +989,10 @@ bool CConf::read()
|
|||||||
m_mqttKeepalive = (unsigned int)::atoi(value);
|
m_mqttKeepalive = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Name") == 0)
|
else if (::strcmp(key, "Name") == 0)
|
||||||
m_mqttName = value;
|
m_mqttName = value;
|
||||||
} else if (section == SECTION_DYNAMIC_TG_CONTROL) {
|
} else if (section == SECTION::DYNAMIC_TG_CONTROL) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_dynamicTGControlEnabled = ::atoi(value) == 1;
|
m_dynamicTGControlEnabled = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_REMOTE_COMMANDS) {
|
} else if (section == SECTION::REMOTE_COMMANDS) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_remoteCommandsEnabled = ::atoi(value) == 1;
|
m_remoteCommandsEnabled = ::atoi(value) == 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2529,12 +2529,15 @@ void CDMRGateway::processDynamicTGControl(const std::string& command)
|
|||||||
{
|
{
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
|
|
||||||
std::stringstream tokeniser(command);
|
|
||||||
|
|
||||||
// Parse the original command into a vector of strings.
|
// Parse the original command into a vector of strings.
|
||||||
std::string token;
|
size_t start = command.find_first_not_of(' ');
|
||||||
while (std::getline(tokeniser, token, ' '))
|
while (start != std::string::npos) {
|
||||||
args.push_back(token);
|
size_t end = command.find_first_of(' ', start);
|
||||||
|
|
||||||
|
args.push_back(command.substr(start, end - start));
|
||||||
|
|
||||||
|
start = command.find_first_not_of(' ', end);
|
||||||
|
}
|
||||||
|
|
||||||
if (args.at(0U) == "DynTG") {
|
if (args.at(0U) == "DynTG") {
|
||||||
if (args.size() < 3) {
|
if (args.size() < 3) {
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||||||
if (m_status == STATUS::RUNNING) {
|
if (m_status == STATUS::RUNNING) {
|
||||||
LogWarning("%s, Login to the master has failed, retrying login ...", m_name.c_str());
|
LogWarning("%s, Login to the master has failed, retrying login ...", m_name.c_str());
|
||||||
WriteJSONStatus("Failed login into DMR Network: " + m_name);
|
WriteJSONStatus("Failed login into DMR Network: " + m_name);
|
||||||
m_status = WAITING_LOGIN;
|
m_status = STATUS::WAITING_LOGIN;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
} else {
|
} else {
|
||||||
@@ -403,7 +403,7 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||||||
if (m_options.empty()) {
|
if (m_options.empty()) {
|
||||||
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
||||||
WriteJSONStatus("Logged into DMR Network: " + m_name);
|
WriteJSONStatus("Logged into DMR Network: " + m_name);
|
||||||
m_status = RUNNING;
|
m_status = STATUS::RUNNING;
|
||||||
} else {
|
} else {
|
||||||
LogDebug("%s, Sending options", m_name.c_str());
|
LogDebug("%s, Sending options", m_name.c_str());
|
||||||
writeOptions();
|
writeOptions();
|
||||||
@@ -415,7 +415,7 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||||||
case STATUS::WAITING_OPTIONS:
|
case STATUS::WAITING_OPTIONS:
|
||||||
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
||||||
WriteJSONStatus("Logged into DMR Network: " + m_name);
|
WriteJSONStatus("Logged into DMR Network: " + m_name);
|
||||||
m_status = RUNNING;
|
m_status = STATUS::RUNNING;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ m_talkerAliasLen(0U)
|
|||||||
m_talkerAliasData = new unsigned char[50U];
|
m_talkerAliasData = new unsigned char[50U];
|
||||||
|
|
||||||
CStopWatch stopWatch;
|
CStopWatch stopWatch;
|
||||||
::srand(stopWatch.start());
|
::srand((unsigned int)stopWatch.start());
|
||||||
}
|
}
|
||||||
|
|
||||||
CMMDVMNetwork::~CMMDVMNetwork()
|
CMMDVMNetwork::~CMMDVMNetwork()
|
||||||
|
|||||||
@@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
CMQTTConnection::CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector<std::pair<std::string, void (*)(const unsigned char*, unsigned int)>>& subs, unsigned int keepalive, MQTT_QOS qos) :
|
CMQTTConnection::CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector<std::pair<std::string, void (*)(const unsigned char*, unsigned int)>>& subs, unsigned int keepalive, MQTT_QOS qos) :
|
||||||
m_host(host),
|
m_host(host),
|
||||||
@@ -30,7 +30,7 @@ m_name(name),
|
|||||||
m_subs(subs),
|
m_subs(subs),
|
||||||
m_keepalive(keepalive),
|
m_keepalive(keepalive),
|
||||||
m_qos(qos),
|
m_qos(qos),
|
||||||
m_mosq(NULL),
|
m_mosq(nullptr),
|
||||||
m_connected(false)
|
m_connected(false)
|
||||||
{
|
{
|
||||||
assert(!host.empty());
|
assert(!host.empty());
|
||||||
@@ -48,8 +48,13 @@ CMQTTConnection::~CMQTTConnection()
|
|||||||
|
|
||||||
bool CMQTTConnection::open()
|
bool CMQTTConnection::open()
|
||||||
{
|
{
|
||||||
m_mosq = ::mosquitto_new(m_name.c_str(), true, this);
|
char name[50U];
|
||||||
if (m_mosq == NULL){
|
::sprintf(name, "DMRGateway.%lld", ::time(nullptr));
|
||||||
|
|
||||||
|
::fprintf(stdout, "DMRGateway (%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");
|
::fprintf(stderr, "MQTT Error newing: Out of memory.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -62,7 +67,7 @@ bool CMQTTConnection::open()
|
|||||||
int rc = ::mosquitto_connect(m_mosq, m_host.c_str(), m_port, m_keepalive);
|
int rc = ::mosquitto_connect(m_mosq, m_host.c_str(), m_port, m_keepalive);
|
||||||
if (rc != MOSQ_ERR_SUCCESS) {
|
if (rc != MOSQ_ERR_SUCCESS) {
|
||||||
::mosquitto_destroy(m_mosq);
|
::mosquitto_destroy(m_mosq);
|
||||||
m_mosq = NULL;
|
m_mosq = nullptr;
|
||||||
::fprintf(stderr, "MQTT Error connecting: %s\n", ::mosquitto_strerror(rc));
|
::fprintf(stderr, "MQTT Error connecting: %s\n", ::mosquitto_strerror(rc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -71,7 +76,7 @@ bool CMQTTConnection::open()
|
|||||||
if (rc != MOSQ_ERR_SUCCESS) {
|
if (rc != MOSQ_ERR_SUCCESS) {
|
||||||
::mosquitto_disconnect(m_mosq);
|
::mosquitto_disconnect(m_mosq);
|
||||||
::mosquitto_destroy(m_mosq);
|
::mosquitto_destroy(m_mosq);
|
||||||
m_mosq = NULL;
|
m_mosq = nullptr;
|
||||||
::fprintf(stderr, "MQTT Error loop starting: %s\n", ::mosquitto_strerror(rc));
|
::fprintf(stderr, "MQTT Error loop starting: %s\n", ::mosquitto_strerror(rc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -81,38 +86,38 @@ bool CMQTTConnection::open()
|
|||||||
|
|
||||||
bool CMQTTConnection::publish(const char* topic, const char* text)
|
bool CMQTTConnection::publish(const char* topic, const char* text)
|
||||||
{
|
{
|
||||||
assert(topic != NULL);
|
assert(topic != nullptr);
|
||||||
assert(text != NULL);
|
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)
|
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)
|
bool CMQTTConnection::publish(const char* topic, const unsigned char* data, unsigned int len)
|
||||||
{
|
{
|
||||||
assert(topic != NULL);
|
assert(topic != nullptr);
|
||||||
assert(data != NULL);
|
assert(data != nullptr);
|
||||||
|
|
||||||
if (!m_connected)
|
if (!m_connected)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (::strchr(topic, '/') == NULL) {
|
if (::strchr(topic, '/') == nullptr) {
|
||||||
char topicEx[100U];
|
char topicEx[100U];
|
||||||
::sprintf(topicEx, "%s/%s", m_name.c_str(), topic);
|
::sprintf(topicEx, "%s/%s", m_name.c_str(), topic);
|
||||||
|
|
||||||
int rc = ::mosquitto_publish(m_mosq, NULL, topicEx, len, data, static_cast<int>(m_qos), false);
|
int rc = ::mosquitto_publish(m_mosq, nullptr, topicEx, len, data, static_cast<int>(m_qos), false);
|
||||||
if (rc != MOSQ_ERR_SUCCESS) {
|
if (rc != MOSQ_ERR_SUCCESS) {
|
||||||
::fprintf(stderr, "MQTT Error publishing: %s\n", ::mosquitto_strerror(rc));
|
::fprintf(stderr, "MQTT Error publishing: %s\n", ::mosquitto_strerror(rc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int rc = ::mosquitto_publish(m_mosq, NULL, topic, len, data, static_cast<int>(m_qos), false);
|
int rc = ::mosquitto_publish(m_mosq, nullptr, topic, len, data, static_cast<int>(m_qos), false);
|
||||||
if (rc != MOSQ_ERR_SUCCESS) {
|
if (rc != MOSQ_ERR_SUCCESS) {
|
||||||
::fprintf(stderr, "MQTT Error publishing: %s\n", ::mosquitto_strerror(rc));
|
::fprintf(stderr, "MQTT Error publishing: %s\n", ::mosquitto_strerror(rc));
|
||||||
return false;
|
return false;
|
||||||
@@ -124,17 +129,17 @@ bool CMQTTConnection::publish(const char* topic, const unsigned char* data, unsi
|
|||||||
|
|
||||||
void CMQTTConnection::close()
|
void CMQTTConnection::close()
|
||||||
{
|
{
|
||||||
if (m_mosq != NULL) {
|
if (m_mosq != nullptr) {
|
||||||
::mosquitto_disconnect(m_mosq);
|
::mosquitto_disconnect(m_mosq);
|
||||||
::mosquitto_destroy(m_mosq);
|
::mosquitto_destroy(m_mosq);
|
||||||
m_mosq = NULL;
|
m_mosq = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMQTTConnection::onConnect(mosquitto* mosq, void* obj, int rc)
|
void CMQTTConnection::onConnect(mosquitto* mosq, void* obj, int rc)
|
||||||
{
|
{
|
||||||
assert(mosq != NULL);
|
assert(mosq != nullptr);
|
||||||
assert(obj != NULL);
|
assert(obj != nullptr);
|
||||||
|
|
||||||
::fprintf(stdout, "MQTT: on_connect: %s\n", ::mosquitto_connack_string(rc));
|
::fprintf(stdout, "MQTT: on_connect: %s\n", ::mosquitto_connack_string(rc));
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
@@ -152,13 +157,13 @@ void CMQTTConnection::onConnect(mosquitto* mosq, void* obj, int rc)
|
|||||||
char topicEx[100U];
|
char topicEx[100U];
|
||||||
::sprintf(topicEx, "%s/%s", p->m_name.c_str(), topic.c_str());
|
::sprintf(topicEx, "%s/%s", p->m_name.c_str(), topic.c_str());
|
||||||
|
|
||||||
rc = ::mosquitto_subscribe(mosq, NULL, topicEx, static_cast<int>(p->m_qos));
|
rc = ::mosquitto_subscribe(mosq, nullptr, topicEx, static_cast<int>(p->m_qos));
|
||||||
if (rc != MOSQ_ERR_SUCCESS) {
|
if (rc != MOSQ_ERR_SUCCESS) {
|
||||||
::fprintf(stderr, "MQTT: error subscribing to %s - %s\n", topicEx, ::mosquitto_strerror(rc));
|
::fprintf(stderr, "MQTT: error subscribing to %s - %s\n", topicEx, ::mosquitto_strerror(rc));
|
||||||
::mosquitto_disconnect(mosq);
|
::mosquitto_disconnect(mosq);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = ::mosquitto_subscribe(mosq, NULL, topic.c_str(), static_cast<int>(p->m_qos));
|
rc = ::mosquitto_subscribe(mosq, nullptr, topic.c_str(), static_cast<int>(p->m_qos));
|
||||||
if (rc != MOSQ_ERR_SUCCESS) {
|
if (rc != MOSQ_ERR_SUCCESS) {
|
||||||
::fprintf(stderr, "MQTT: error subscribing to %s - %s\n", topic.c_str(), ::mosquitto_strerror(rc));
|
::fprintf(stderr, "MQTT: error subscribing to %s - %s\n", topic.c_str(), ::mosquitto_strerror(rc));
|
||||||
::mosquitto_disconnect(mosq);
|
::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)
|
void CMQTTConnection::onSubscribe(mosquitto* mosq, void* obj, int mid, int qosCount, const int* grantedQOS)
|
||||||
{
|
{
|
||||||
assert(mosq != NULL);
|
assert(mosq != nullptr);
|
||||||
assert(obj != NULL);
|
assert(obj != nullptr);
|
||||||
assert(grantedQOS != NULL);
|
assert(grantedQOS != nullptr);
|
||||||
|
|
||||||
for (int i = 0; i < qosCount; i++)
|
for (int i = 0; i < qosCount; i++)
|
||||||
::fprintf(stdout, "MQTT: on_subscribe: %d:%d\n", i, grantedQOS[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)
|
void CMQTTConnection::onMessage(mosquitto* mosq, void* obj, const mosquitto_message* message)
|
||||||
{
|
{
|
||||||
assert(mosq != NULL);
|
assert(mosq != nullptr);
|
||||||
assert(obj != NULL);
|
assert(obj != nullptr);
|
||||||
assert(message != NULL);
|
assert(message != nullptr);
|
||||||
|
|
||||||
CMQTTConnection* p = static_cast<CMQTTConnection*>(obj);
|
CMQTTConnection* p = static_cast<CMQTTConnection*>(obj);
|
||||||
|
|
||||||
@@ -200,8 +205,8 @@ void CMQTTConnection::onMessage(mosquitto* mosq, void* obj, const mosquitto_mess
|
|||||||
|
|
||||||
void CMQTTConnection::onDisconnect(mosquitto* mosq, void* obj, int rc)
|
void CMQTTConnection::onDisconnect(mosquitto* mosq, void* obj, int rc)
|
||||||
{
|
{
|
||||||
assert(mosq != NULL);
|
assert(mosq != nullptr);
|
||||||
assert(obj != NULL);
|
assert(obj != nullptr);
|
||||||
|
|
||||||
::fprintf(stdout, "MQTT: on_disconnect: %s\n", ::mosquitto_reason_string(rc));
|
::fprintf(stdout, "MQTT: on_disconnect: %s\n", ::mosquitto_reason_string(rc));
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,15 +24,15 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum MQTT_QOS {
|
enum class MQTT_QOS : int {
|
||||||
MQTT_QOS_AT_MODE_ONCE = 0U,
|
AT_MODE_ONCE = 0,
|
||||||
MQTT_QOS_AT_LEAST_ONCE = 1U,
|
AT_LEAST_ONCE = 1,
|
||||||
MQTT_QOS_EXACTLY_ONCE = 2U
|
EXACTLY_ONCE = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMQTTConnection {
|
class CMQTTConnection {
|
||||||
public:
|
public:
|
||||||
CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector<std::pair<std::string, void (*)(const unsigned char*, unsigned int)>>& 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<std::pair<std::string, void (*)(const unsigned char*, unsigned int)>>& subs, unsigned int keepalive, MQTT_QOS qos = MQTT_QOS::EXACTLY_ONCE);
|
||||||
~CMQTTConnection();
|
~CMQTTConnection();
|
||||||
|
|
||||||
bool open();
|
bool open();
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ extern CMQTTConnection* m_mqtt;
|
|||||||
|
|
||||||
CRemoteControl::CRemoteControl(CDMRGateway* host) :
|
CRemoteControl::CRemoteControl(CDMRGateway* host) :
|
||||||
m_host(host),
|
m_host(host),
|
||||||
m_command(RCD_NONE),
|
m_command(REMOTE_COMMAND::NONE),
|
||||||
m_args()
|
m_args()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -47,46 +47,49 @@ CRemoteControl::~CRemoteControl()
|
|||||||
|
|
||||||
REMOTE_COMMAND CRemoteControl::processCommand(const std::string& command)
|
REMOTE_COMMAND CRemoteControl::processCommand(const std::string& command)
|
||||||
{
|
{
|
||||||
m_command = RCD_NONE;
|
m_command = REMOTE_COMMAND::NONE;
|
||||||
m_args.clear();
|
m_args.clear();
|
||||||
|
|
||||||
std::string replyStr = "OK";
|
std::string replyStr = "OK";
|
||||||
|
|
||||||
std::stringstream tokeniser(command);
|
|
||||||
|
|
||||||
// Parse the original command into a vector of strings.
|
// Parse the original command into a vector of strings.
|
||||||
std::string token;
|
size_t start = command.find_first_not_of(' ');
|
||||||
while (std::getline(tokeniser, token, ' '))
|
while (start != std::string::npos) {
|
||||||
m_args.push_back(token);
|
size_t end = command.find_first_of(' ', start);
|
||||||
|
|
||||||
|
m_args.push_back(command.substr(start, end - start));
|
||||||
|
|
||||||
|
start = command.find_first_not_of(' ', end);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) {
|
if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) {
|
||||||
if (m_args.at(1U) == "net1")
|
if (m_args.at(1U) == "net1")
|
||||||
m_command = RCD_ENABLE_NETWORK1;
|
m_command = REMOTE_COMMAND::ENABLE_NETWORK1;
|
||||||
else if (m_args.at(1U) == "net2")
|
else if (m_args.at(1U) == "net2")
|
||||||
m_command = RCD_ENABLE_NETWORK2;
|
m_command = REMOTE_COMMAND::ENABLE_NETWORK2;
|
||||||
else if (m_args.at(1U) == "net3")
|
else if (m_args.at(1U) == "net3")
|
||||||
m_command = RCD_ENABLE_NETWORK3;
|
m_command = REMOTE_COMMAND::ENABLE_NETWORK3;
|
||||||
else if (m_args.at(1U) == "net4")
|
else if (m_args.at(1U) == "net4")
|
||||||
m_command = RCD_ENABLE_NETWORK4;
|
m_command = REMOTE_COMMAND::ENABLE_NETWORK4;
|
||||||
else if (m_args.at(1U) == "net5")
|
else if (m_args.at(1U) == "net5")
|
||||||
m_command = RCD_ENABLE_NETWORK5;
|
m_command = REMOTE_COMMAND::ENABLE_NETWORK5;
|
||||||
else if (m_args.at(1U) == "xlx")
|
else if (m_args.at(1U) == "xlx")
|
||||||
m_command = RCD_ENABLE_XLX;
|
m_command = REMOTE_COMMAND::ENABLE_XLX;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
} else if (m_args.at(0U) == "disable" && m_args.size() >= DISABLE_ARGS) {
|
} else if (m_args.at(0U) == "disable" && m_args.size() >= DISABLE_ARGS) {
|
||||||
if (m_args.at(1U) == "net1")
|
if (m_args.at(1U) == "net1")
|
||||||
m_command = RCD_DISABLE_NETWORK1;
|
m_command = REMOTE_COMMAND::DISABLE_NETWORK1;
|
||||||
else if (m_args.at(1U) == "net2")
|
else if (m_args.at(1U) == "net2")
|
||||||
m_command = RCD_DISABLE_NETWORK2;
|
m_command = REMOTE_COMMAND::DISABLE_NETWORK2;
|
||||||
else if (m_args.at(1U) == "net3")
|
else if (m_args.at(1U) == "net3")
|
||||||
m_command = RCD_DISABLE_NETWORK3;
|
m_command = REMOTE_COMMAND::DISABLE_NETWORK3;
|
||||||
else if (m_args.at(1U) == "net4")
|
else if (m_args.at(1U) == "net4")
|
||||||
m_command = RCD_DISABLE_NETWORK4;
|
m_command = REMOTE_COMMAND::DISABLE_NETWORK4;
|
||||||
else if (m_args.at(1U) == "net5")
|
else if (m_args.at(1U) == "net5")
|
||||||
m_command = RCD_DISABLE_NETWORK5;
|
m_command = REMOTE_COMMAND::DISABLE_NETWORK5;
|
||||||
else if (m_args.at(1U) == "xlx")
|
else if (m_args.at(1U) == "xlx")
|
||||||
m_command = RCD_DISABLE_XLX;
|
m_command = REMOTE_COMMAND::DISABLE_XLX;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
} else if (m_args.at(0U) == "status") {
|
} else if (m_args.at(0U) == "status") {
|
||||||
@@ -95,22 +98,22 @@ REMOTE_COMMAND CRemoteControl::processCommand(const std::string& command)
|
|||||||
else
|
else
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
|
|
||||||
m_command = RCD_CONNECTION_STATUS;
|
m_command = REMOTE_COMMAND::CONNECTION_STATUS;
|
||||||
} else if (m_args.at(0U) == "hosts") {
|
} else if (m_args.at(0U) == "hosts") {
|
||||||
if (m_host != nullptr)
|
if (m_host != nullptr)
|
||||||
m_host->buildNetworkHostsString(replyStr);
|
m_host->buildNetworkHostsString(replyStr);
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
|
|
||||||
m_command = RCD_CONFIG_HOSTS;
|
m_command = REMOTE_COMMAND::CONFIG_HOSTS;
|
||||||
} else {
|
} else {
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[200U];
|
char buffer[200U];
|
||||||
::snprintf(buffer, 200, "%s remote command of \"%s\" received", ((m_command == RCD_NONE) ? "Invalid" : "Valid"), command.c_str());
|
::snprintf(buffer, 200, "%s remote command of \"%s\" received", ((m_command == REMOTE_COMMAND::NONE) ? "Invalid" : "Valid"), command.c_str());
|
||||||
|
|
||||||
if (m_command == RCD_NONE) {
|
if (m_command == REMOTE_COMMAND::NONE) {
|
||||||
m_args.clear();
|
m_args.clear();
|
||||||
LogWarning(buffer);
|
LogWarning(buffer);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user