mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 15:09:23 +08:00
Use MQTT for the remote command handling.
This commit is contained in:
15
Conf.cpp
15
Conf.cpp
@@ -303,9 +303,7 @@ m_ax25NetworkSpeed(9600U),
|
|||||||
m_ax25NetworkDebug(false),
|
m_ax25NetworkDebug(false),
|
||||||
m_lockFileEnabled(false),
|
m_lockFileEnabled(false),
|
||||||
m_lockFileName(),
|
m_lockFileName(),
|
||||||
m_remoteControlEnabled(false),
|
m_remoteControlEnabled(false)
|
||||||
m_remoteControlAddress("127.0.0.1"),
|
|
||||||
m_remoteControlPort(0U)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,8 +1029,6 @@ bool CConf::read()
|
|||||||
} else if (section == SECTION_REMOTE_CONTROL) {
|
} else if (section == SECTION_REMOTE_CONTROL) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_remoteControlEnabled = ::atoi(value) == 1;
|
m_remoteControlEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Port") == 0)
|
|
||||||
m_remoteControlPort = (unsigned short)::atoi(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2251,12 +2247,3 @@ bool CConf::getRemoteControlEnabled() const
|
|||||||
return m_remoteControlEnabled;
|
return m_remoteControlEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CConf::getRemoteControlAddress() const
|
|
||||||
{
|
|
||||||
return m_remoteControlAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short CConf::getRemoteControlPort() const
|
|
||||||
{
|
|
||||||
return m_remoteControlPort;
|
|
||||||
}
|
|
||||||
|
|||||||
4
Conf.h
4
Conf.h
@@ -329,8 +329,6 @@ public:
|
|||||||
|
|
||||||
// The Remote Control section
|
// The Remote Control section
|
||||||
bool getRemoteControlEnabled() const;
|
bool getRemoteControlEnabled() const;
|
||||||
std::string getRemoteControlAddress() const;
|
|
||||||
unsigned short getRemoteControlPort() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_file;
|
std::string m_file;
|
||||||
@@ -604,8 +602,6 @@ private:
|
|||||||
std::string m_lockFileName;
|
std::string m_lockFileName;
|
||||||
|
|
||||||
bool m_remoteControlEnabled;
|
bool m_remoteControlEnabled;
|
||||||
std::string m_remoteControlAddress;
|
|
||||||
unsigned short m_remoteControlPort;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -312,5 +312,4 @@ File=/tmp/MMDVM_Active.lck
|
|||||||
|
|
||||||
[Remote Control]
|
[Remote Control]
|
||||||
Enable=0
|
Enable=0
|
||||||
Address=127.0.0.1
|
|
||||||
Port=7642
|
|
||||||
|
|||||||
@@ -769,22 +769,8 @@ int CMMDVMHost::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool remoteControlEnabled = m_conf.getRemoteControlEnabled();
|
bool remoteControlEnabled = m_conf.getRemoteControlEnabled();
|
||||||
if (remoteControlEnabled) {
|
if (remoteControlEnabled)
|
||||||
std::string address = m_conf.getRemoteControlAddress();
|
m_remoteControl = new CRemoteControl(this, m_mqtt);
|
||||||
unsigned short port = m_conf.getRemoteControlPort();
|
|
||||||
|
|
||||||
LogInfo("Remote Control Parameters");
|
|
||||||
LogInfo(" Address: %s", address.c_str());
|
|
||||||
LogInfo(" Port: %hu", port);
|
|
||||||
|
|
||||||
m_remoteControl = new CRemoteControl(this, address, port);
|
|
||||||
|
|
||||||
ret = m_remoteControl->open();
|
|
||||||
if (!ret) {
|
|
||||||
delete m_remoteControl;
|
|
||||||
m_remoteControl = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setMode(MODE_IDLE);
|
setMode(MODE_IDLE);
|
||||||
|
|
||||||
@@ -1205,8 +1191,6 @@ int CMMDVMHost::run()
|
|||||||
m_modem->writeTransparentData(data, len);
|
m_modem->writeTransparentData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteControl();
|
|
||||||
|
|
||||||
unsigned int ms = stopWatch.elapsed();
|
unsigned int ms = stopWatch.elapsed();
|
||||||
stopWatch.start();
|
stopWatch.start();
|
||||||
|
|
||||||
@@ -1387,10 +1371,7 @@ int CMMDVMHost::run()
|
|||||||
delete transparentSocket;
|
delete transparentSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_remoteControl != NULL) {
|
delete m_remoteControl;
|
||||||
m_remoteControl->close();
|
|
||||||
delete m_remoteControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("Stopping protocol handlers");
|
LogInfo("Stopping protocol handlers");
|
||||||
writeJSONMessage("Stopping protocol handlers");
|
writeJSONMessage("Stopping protocol handlers");
|
||||||
@@ -2515,12 +2496,12 @@ void CMMDVMHost::removeLockFile() const
|
|||||||
::remove(m_lockFileName.c_str());
|
::remove(m_lockFileName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMMDVMHost::remoteControl()
|
void CMMDVMHost::remoteControl(const std::string& commandString)
|
||||||
{
|
{
|
||||||
if (m_remoteControl == NULL)
|
if (m_remoteControl == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
REMOTE_COMMAND command = m_remoteControl->getCommand();
|
REMOTE_COMMAND command = m_remoteControl->getCommand(commandString);
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case RCD_MODE_IDLE:
|
case RCD_MODE_IDLE:
|
||||||
m_fixedMode = false;
|
m_fixedMode = false;
|
||||||
@@ -2805,6 +2786,9 @@ void CMMDVMHost::writeJSONMessage(const std::string& message)
|
|||||||
|
|
||||||
void CMMDVMHost::onCommand(const std::string& command)
|
void CMMDVMHost::onCommand(const std::string& command)
|
||||||
{
|
{
|
||||||
|
assert(host != NULL);
|
||||||
|
|
||||||
|
host->remoteControl(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMMDVMHost::onDisplay(const std::string& message)
|
void CMMDVMHost::onDisplay(const std::string& message)
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ private:
|
|||||||
bool createFMNetwork();
|
bool createFMNetwork();
|
||||||
bool createAX25Network();
|
bool createAX25Network();
|
||||||
|
|
||||||
void remoteControl();
|
void remoteControl(const std::string& commandString);
|
||||||
void processModeCommand(unsigned char mode, unsigned int timeout);
|
void processModeCommand(unsigned char mode, unsigned int timeout);
|
||||||
void processEnableCommand(bool& mode, bool enabled);
|
void processEnableCommand(bool& mode, bool enabled);
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ VisualStudioVersion = 15.0.28307.271
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MMDVMHost", "MMDVMHost.vcxproj", "{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MMDVMHost", "MMDVMHost.vcxproj", "{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RemoteCommand", "RemoteCommand.vcxproj", "{5A61AB93-58BB-413A-BBD9-A26284CB37AE}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@@ -23,14 +21,6 @@ Global
|
|||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x64.Build.0 = Release|x64
|
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x64.Build.0 = Release|x64
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x86.ActiveCfg = Release|Win32
|
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x86.Build.0 = Release|Win32
|
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x86.Build.0 = Release|Win32
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x64.Build.0 = Release|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x86.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -17,21 +17,17 @@ OBJECTS = \
|
|||||||
POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialPort.o StopWatch.o Sync.o SHA256.o Thread.o \
|
POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialPort.o StopWatch.o Sync.o SHA256.o Thread.o \
|
||||||
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
all: MMDVMHost
|
||||||
|
|
||||||
MMDVMHost: GitVersion.h $(OBJECTS)
|
MMDVMHost: GitVersion.h $(OBJECTS)
|
||||||
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o MMDVMHost
|
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o MMDVMHost
|
||||||
|
|
||||||
RemoteCommand: Log.o MQTTConnection.o RemoteCommand.o UDPSocket.o
|
|
||||||
$(CXX) Log.o MQTTConnection.o RemoteCommand.o UDPSocket.o $(CFLAGS) $(LIBS) -o RemoteCommand
|
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
.PHONY install:
|
.PHONY install:
|
||||||
install: all
|
install: all
|
||||||
install -m 755 MMDVMHost /usr/local/bin/
|
install -m 755 MMDVMHost /usr/local/bin/
|
||||||
install -m 755 RemoteCommand /usr/local/bin/
|
|
||||||
|
|
||||||
.PHONY install-service:
|
.PHONY install-service:
|
||||||
install-service: install /etc/MMDVM.ini
|
install-service: install /etc/MMDVM.ini
|
||||||
@@ -56,7 +52,7 @@ uninstall-service:
|
|||||||
@rm -f /lib/systemd/system/mmdvmhost.service || true
|
@rm -f /lib/systemd/system/mmdvmhost.service || true
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
$(RM) MMDVMHost *.o *.d *.bak *~ GitVersion.h
|
||||||
|
|
||||||
# Export the current git version if the index file exists, else 000...
|
# Export the current git version if the index file exists, else 000...
|
||||||
GitVersion.h:
|
GitVersion.h:
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019,2020 by Jonathan Naylor G4KLX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "RemoteCommand.h"
|
|
||||||
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 1024U;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
if (argc < 3) {
|
|
||||||
::fprintf(stderr, "Usage: RemoteCommand <port> <command> [argument]\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int port = (unsigned int)::atoi(argv[1]);
|
|
||||||
std::string cmd = std::string(argv[2]);
|
|
||||||
|
|
||||||
for (int i = 3; i < argc; i++) {
|
|
||||||
cmd += " ";
|
|
||||||
cmd += std::string(argv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port == 0U) {
|
|
||||||
::fprintf(stderr, "RemoteCommand: invalid port number - %s\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CRemoteCommand* command = new CRemoteCommand(port);
|
|
||||||
|
|
||||||
return command->send(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
CRemoteCommand::CRemoteCommand(unsigned int port) :
|
|
||||||
m_port(port)
|
|
||||||
{
|
|
||||||
CUDPSocket::startup();
|
|
||||||
|
|
||||||
::LogInitialise(false, ".", "RemoteCommand", 2U, 2U, 2U, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CRemoteCommand::~CRemoteCommand()
|
|
||||||
{
|
|
||||||
::LogFinalise();
|
|
||||||
|
|
||||||
CUDPSocket::shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
int CRemoteCommand::send(const std::string& command)
|
|
||||||
{
|
|
||||||
sockaddr_storage addr;
|
|
||||||
unsigned int addrLen;
|
|
||||||
char buffer[BUFFER_LENGTH];
|
|
||||||
int retStatus = 0;
|
|
||||||
|
|
||||||
if (CUDPSocket::lookup("127.0.0.1", m_port, addr, addrLen) != 0) {
|
|
||||||
::fprintf(stderr, "Unable to resolve the address of the host\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CUDPSocket socket(0U);
|
|
||||||
|
|
||||||
bool ret = socket.open(addr);
|
|
||||||
if (!ret)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
ret = socket.write((unsigned char*)command.c_str(), command.length(), addr, addrLen);
|
|
||||||
if (!ret) {
|
|
||||||
socket.close();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
::fprintf(stdout, "Command sent: \"%s\" to port: %u\n", command.c_str(), m_port);
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
||||||
|
|
||||||
int len = socket.read((unsigned char*)buffer, BUFFER_LENGTH, addr, addrLen);
|
|
||||||
if (len > 0) {
|
|
||||||
buffer[len] = '\0';
|
|
||||||
::fprintf(stdout, "%s\n", buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
retStatus = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.close();
|
|
||||||
|
|
||||||
return retStatus;
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 by Jonathan Naylor G4KLX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RemoteCommand_H
|
|
||||||
#define RemoteCommand_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class CRemoteCommand
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CRemoteCommand(unsigned int port);
|
|
||||||
~CRemoteCommand();
|
|
||||||
|
|
||||||
int send(const std::string& command);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int m_port;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019,2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2019,2020,2021,2023 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
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned int SET_MODE_ARGS = 2U;
|
const unsigned int SET_MODE_ARGS = 2U;
|
||||||
const unsigned int ENABLE_ARGS = 2U;
|
const unsigned int ENABLE_ARGS = 2U;
|
||||||
@@ -31,159 +30,142 @@ const unsigned int DISABLE_ARGS = 2U;
|
|||||||
const unsigned int PAGE_ARGS = 3U;
|
const unsigned int PAGE_ARGS = 3U;
|
||||||
const unsigned int CW_ARGS = 2U;
|
const unsigned int CW_ARGS = 2U;
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 100U;
|
|
||||||
|
|
||||||
CRemoteControl::CRemoteControl(CMMDVMHost *host, const std::string address, unsigned int port) :
|
CRemoteControl::CRemoteControl(CMMDVMHost *host, CMQTTConnection* mqtt) :
|
||||||
m_host(host),
|
m_host(host),
|
||||||
m_socket(address, port),
|
m_mqtt(mqtt),
|
||||||
m_command(RCD_NONE),
|
m_command(RCD_NONE),
|
||||||
m_args()
|
m_args()
|
||||||
{
|
{
|
||||||
assert(port > 0U);
|
assert(host != NULL);
|
||||||
|
assert(mqtt != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRemoteControl::~CRemoteControl()
|
CRemoteControl::~CRemoteControl()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRemoteControl::open()
|
REMOTE_COMMAND CRemoteControl::getCommand(const std::string& command)
|
||||||
{
|
|
||||||
return m_socket.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
REMOTE_COMMAND CRemoteControl::getCommand()
|
|
||||||
{
|
{
|
||||||
m_command = RCD_NONE;
|
m_command = RCD_NONE;
|
||||||
m_args.clear();
|
m_args.clear();
|
||||||
|
|
||||||
char command[BUFFER_LENGTH];
|
std::string reply = "OK";
|
||||||
char buffer[BUFFER_LENGTH * 2];
|
|
||||||
std::string replyStr = "OK";
|
|
||||||
sockaddr_storage address;
|
|
||||||
unsigned int addrlen;
|
|
||||||
int ret = m_socket.read((unsigned char*)buffer, BUFFER_LENGTH, address, addrlen);
|
|
||||||
if (ret > 0) {
|
|
||||||
buffer[ret] = '\0';
|
|
||||||
|
|
||||||
// Make a copy of the original command for logging.
|
std::stringstream tokeniser(command);
|
||||||
::strcpy(command, buffer);
|
|
||||||
|
|
||||||
// Parse the original command into a vector of strings.
|
// Parse the original command into a vector of strings.
|
||||||
char* b = buffer;
|
std::string token;
|
||||||
char* p = NULL;
|
while (std::getline(tokeniser, token, ' '))
|
||||||
while ((p = ::strtok(b, " ")) != NULL) {
|
m_args.push_back(token);
|
||||||
b = NULL;
|
|
||||||
m_args.push_back(std::string(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_args.at(0U) == "mode" && m_args.size() >= SET_MODE_ARGS) {
|
if (m_args.at(0U) == "mode" && m_args.size() >= SET_MODE_ARGS) {
|
||||||
// Mode command is in the form of "mode <mode> [<timeout>|fixed]"
|
// Mode command is in the form of "mode <mode> [<timeout>|fixed]"
|
||||||
if (m_args.at(1U) == "idle")
|
if (m_args.at(1U) == "idle")
|
||||||
m_command = RCD_MODE_IDLE;
|
m_command = RCD_MODE_IDLE;
|
||||||
else if (m_args.at(1U) == "lockout")
|
else if (m_args.at(1U) == "lockout")
|
||||||
m_command = RCD_MODE_LOCKOUT;
|
m_command = RCD_MODE_LOCKOUT;
|
||||||
else if (m_args.at(1U) == "d-star")
|
else if (m_args.at(1U) == "d-star")
|
||||||
m_command = RCD_MODE_DSTAR;
|
m_command = RCD_MODE_DSTAR;
|
||||||
else if (m_args.at(1U) == "dmr")
|
else if (m_args.at(1U) == "dmr")
|
||||||
m_command = RCD_MODE_DMR;
|
m_command = RCD_MODE_DMR;
|
||||||
else if (m_args.at(1U) == "ysf")
|
else if (m_args.at(1U) == "ysf")
|
||||||
m_command = RCD_MODE_YSF;
|
m_command = RCD_MODE_YSF;
|
||||||
else if (m_args.at(1U) == "p25")
|
else if (m_args.at(1U) == "p25")
|
||||||
m_command = RCD_MODE_P25;
|
m_command = RCD_MODE_P25;
|
||||||
else if (m_args.at(1U) == "nxdn")
|
else if (m_args.at(1U) == "nxdn")
|
||||||
m_command = RCD_MODE_NXDN;
|
m_command = RCD_MODE_NXDN;
|
||||||
else if (m_args.at(1U) == "m17")
|
else if (m_args.at(1U) == "m17")
|
||||||
m_command = RCD_MODE_M17;
|
m_command = RCD_MODE_M17;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
reply = "KO";
|
||||||
} else if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) {
|
} else if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) {
|
||||||
if (m_args.at(1U) == "dstar")
|
if (m_args.at(1U) == "dstar")
|
||||||
m_command = RCD_ENABLE_DSTAR;
|
m_command = RCD_ENABLE_DSTAR;
|
||||||
else if (m_args.at(1U) == "dmr")
|
else if (m_args.at(1U) == "dmr")
|
||||||
m_command = RCD_ENABLE_DMR;
|
m_command = RCD_ENABLE_DMR;
|
||||||
else if (m_args.at(1U) == "ysf")
|
else if (m_args.at(1U) == "ysf")
|
||||||
m_command = RCD_ENABLE_YSF;
|
m_command = RCD_ENABLE_YSF;
|
||||||
else if (m_args.at(1U) == "p25")
|
else if (m_args.at(1U) == "p25")
|
||||||
m_command = RCD_ENABLE_P25;
|
m_command = RCD_ENABLE_P25;
|
||||||
else if (m_args.at(1U) == "nxdn")
|
else if (m_args.at(1U) == "nxdn")
|
||||||
m_command = RCD_ENABLE_NXDN;
|
m_command = RCD_ENABLE_NXDN;
|
||||||
else if (m_args.at(1U) == "m17")
|
else if (m_args.at(1U) == "m17")
|
||||||
m_command = RCD_ENABLE_M17;
|
m_command = RCD_ENABLE_M17;
|
||||||
else if (m_args.at(1U) == "fm")
|
else if (m_args.at(1U) == "fm")
|
||||||
m_command = RCD_ENABLE_FM;
|
m_command = RCD_ENABLE_FM;
|
||||||
else if (m_args.at(1U) == "ax25")
|
else if (m_args.at(1U) == "ax25")
|
||||||
m_command = RCD_ENABLE_AX25;
|
m_command = RCD_ENABLE_AX25;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
reply = "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) == "dstar")
|
if (m_args.at(1U) == "dstar")
|
||||||
m_command = RCD_DISABLE_DSTAR;
|
m_command = RCD_DISABLE_DSTAR;
|
||||||
else if (m_args.at(1U) == "dmr")
|
else if (m_args.at(1U) == "dmr")
|
||||||
m_command = RCD_DISABLE_DMR;
|
m_command = RCD_DISABLE_DMR;
|
||||||
else if (m_args.at(1U) == "ysf")
|
else if (m_args.at(1U) == "ysf")
|
||||||
m_command = RCD_DISABLE_YSF;
|
m_command = RCD_DISABLE_YSF;
|
||||||
else if (m_args.at(1U) == "p25")
|
else if (m_args.at(1U) == "p25")
|
||||||
m_command = RCD_DISABLE_P25;
|
m_command = RCD_DISABLE_P25;
|
||||||
else if (m_args.at(1U) == "nxdn")
|
else if (m_args.at(1U) == "nxdn")
|
||||||
m_command = RCD_DISABLE_NXDN;
|
m_command = RCD_DISABLE_NXDN;
|
||||||
else if (m_args.at(1U) == "m17")
|
else if (m_args.at(1U) == "m17")
|
||||||
m_command = RCD_DISABLE_M17;
|
m_command = RCD_DISABLE_M17;
|
||||||
else if (m_args.at(1U) == "fm")
|
else if (m_args.at(1U) == "fm")
|
||||||
m_command = RCD_DISABLE_FM;
|
m_command = RCD_DISABLE_FM;
|
||||||
else if (m_args.at(1U) == "ax25")
|
else if (m_args.at(1U) == "ax25")
|
||||||
m_command = RCD_DISABLE_AX25;
|
m_command = RCD_DISABLE_AX25;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
reply = "KO";
|
||||||
} else if (m_args.at(0U) == "page" && m_args.size() >= PAGE_ARGS) {
|
} else if (m_args.at(0U) == "page" && m_args.size() >= PAGE_ARGS) {
|
||||||
// Page command is in the form of "page <ric> <message>"
|
// Page command is in the form of "page <ric> <message>"
|
||||||
m_command = RCD_PAGE;
|
m_command = RCD_PAGE;
|
||||||
} else if (m_args.at(0U) == "page_bcd" && m_args.size() >= PAGE_ARGS) {
|
} else if (m_args.at(0U) == "page_bcd" && m_args.size() >= PAGE_ARGS) {
|
||||||
// BCD page command is in the form of "page_bcd <ric> <bcd message>"
|
// BCD page command is in the form of "page_bcd <ric> <bcd message>"
|
||||||
m_command = RCD_PAGE_BCD;
|
m_command = RCD_PAGE_BCD;
|
||||||
} else if (m_args.at(0U) == "page_a1" && m_args.size() == 2) {
|
} else if (m_args.at(0U) == "page_a1" && m_args.size() == 2) {
|
||||||
// Alert1 page command is in the form of "page_a1 <ric>"
|
// Alert1 page command is in the form of "page_a1 <ric>"
|
||||||
m_command = RCD_PAGE_A1;
|
m_command = RCD_PAGE_A1;
|
||||||
} else if (m_args.at(0U) == "page_a2" && m_args.size() >= PAGE_ARGS) {
|
} else if (m_args.at(0U) == "page_a2" && m_args.size() >= PAGE_ARGS) {
|
||||||
// Alert2 page command is in the form of "page_a2 <ric> <message>"
|
// Alert2 page command is in the form of "page_a2 <ric> <message>"
|
||||||
m_command = RCD_PAGE_A2;
|
m_command = RCD_PAGE_A2;
|
||||||
} else if (m_args.at(0U) == "cw" && m_args.size() >= CW_ARGS) {
|
} else if (m_args.at(0U) == "cw" && m_args.size() >= CW_ARGS) {
|
||||||
// CW command is in the form of "cw <message>"
|
// CW command is in the form of "cw <message>"
|
||||||
m_command = RCD_CW;
|
m_command = RCD_CW;
|
||||||
} else if (m_args.at(0U) == "reload") {
|
} else if (m_args.at(0U) == "reload") {
|
||||||
// Reload command is in the form of "reload"
|
// Reload command is in the form of "reload"
|
||||||
m_command = RCD_RELOAD;
|
m_command = RCD_RELOAD;
|
||||||
} else if (m_args.at(0U) == "status") {
|
} else if (m_args.at(0U) == "status") {
|
||||||
if (m_host != NULL) {
|
if (m_host != NULL) {
|
||||||
m_host->buildNetworkStatusString(replyStr);
|
m_host->buildNetworkStatusString(reply);
|
||||||
} else {
|
|
||||||
replyStr = "KO";
|
|
||||||
}
|
|
||||||
|
|
||||||
m_command = RCD_CONNECTION_STATUS;
|
|
||||||
} else if (m_args.at(0U) == "hosts") {
|
|
||||||
if (m_host != NULL) {
|
|
||||||
m_host->buildNetworkHostsString(replyStr);
|
|
||||||
} else {
|
|
||||||
replyStr = "KO";
|
|
||||||
}
|
|
||||||
|
|
||||||
m_command = RCD_CONFIG_HOSTS;
|
|
||||||
} else {
|
} else {
|
||||||
replyStr = "KO";
|
reply = "KO";
|
||||||
}
|
}
|
||||||
|
|
||||||
::snprintf(buffer, BUFFER_LENGTH * 2, "%s remote command of \"%s\" received", ((m_command == RCD_NONE) ? "Invalid" : "Valid"), command);
|
m_command = RCD_CONNECTION_STATUS;
|
||||||
if (m_command == RCD_NONE) {
|
} else if (m_args.at(0U) == "hosts") {
|
||||||
m_args.clear();
|
if (m_host != NULL) {
|
||||||
LogWarning(buffer);
|
m_host->buildNetworkHostsString(reply);
|
||||||
} else {
|
} else {
|
||||||
#if !defined(REMOTE_COMMAND_NO_LOG)
|
reply = "KO";
|
||||||
LogMessage(buffer);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_socket.write((unsigned char*)replyStr.c_str(), replyStr.length(), address, addrlen);
|
m_command = RCD_CONFIG_HOSTS;
|
||||||
|
} else {
|
||||||
|
reply = "KO";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char buffer[200U];
|
||||||
|
::snprintf(buffer, 200, "%s remote command of \"%s\" received", ((m_command == RCD_NONE) ? "Invalid" : "Valid"), command.c_str());
|
||||||
|
|
||||||
|
if (m_command == RCD_NONE) {
|
||||||
|
m_args.clear();
|
||||||
|
LogWarning(buffer);
|
||||||
|
} else {
|
||||||
|
LogMessage(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mqtt->publish("command", reply.c_str());
|
||||||
|
|
||||||
return m_command;
|
return m_command;
|
||||||
}
|
}
|
||||||
@@ -254,7 +236,3 @@ int CRemoteControl::getArgInt(unsigned int n) const
|
|||||||
return ::atoi(getArgString(n).c_str());
|
return ::atoi(getArgString(n).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRemoteControl::close()
|
|
||||||
{
|
|
||||||
m_socket.close();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019,2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2019,2020,2021,2023 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
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
#ifndef RemoteControl_H
|
#ifndef RemoteControl_H
|
||||||
#define RemoteControl_H
|
#define RemoteControl_H
|
||||||
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "MQTTConnection.h"
|
||||||
|
|
||||||
class CMMDVMHost;
|
class CMMDVMHost;
|
||||||
|
|
||||||
enum REMOTE_COMMAND {
|
enum REMOTE_COMMAND {
|
||||||
@@ -65,12 +65,10 @@ enum REMOTE_COMMAND {
|
|||||||
|
|
||||||
class CRemoteControl {
|
class CRemoteControl {
|
||||||
public:
|
public:
|
||||||
CRemoteControl(class CMMDVMHost *host, const std::string address, unsigned int port);
|
CRemoteControl(class CMMDVMHost *host, CMQTTConnection* mqtt);
|
||||||
~CRemoteControl();
|
~CRemoteControl();
|
||||||
|
|
||||||
bool open();
|
REMOTE_COMMAND getCommand(const std::string& command);
|
||||||
|
|
||||||
REMOTE_COMMAND getCommand();
|
|
||||||
|
|
||||||
unsigned int getArgCount() const;
|
unsigned int getArgCount() const;
|
||||||
|
|
||||||
@@ -78,11 +76,9 @@ public:
|
|||||||
unsigned int getArgUInt(unsigned int n) const;
|
unsigned int getArgUInt(unsigned int n) const;
|
||||||
signed int getArgInt(unsigned int n) const;
|
signed int getArgInt(unsigned int n) const;
|
||||||
|
|
||||||
void close();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CMMDVMHost* m_host;
|
CMMDVMHost* m_host;
|
||||||
CUDPSocket m_socket;
|
CMQTTConnection* m_mqtt;
|
||||||
REMOTE_COMMAND m_command;
|
REMOTE_COMMAND m_command;
|
||||||
std::vector<std::string> m_args;
|
std::vector<std::string> m_args;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user