From 42a48209d4b9aff5fd508c05ae8c5dffda9dcb95 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 7 Jan 2019 11:03:37 +0000 Subject: [PATCH] Add remote control interface. --- Conf.cpp | 25 ++++++++++++++-- Conf.h | 9 +++++- MMDVM.ini | 3 ++ MMDVMHost.cpp | 36 ++++++++++++++++++++++- MMDVMHost.vcxproj | 2 ++ MMDVMHost.vcxproj.filters | 6 ++++ Makefile | 2 +- Makefile.Pi | 2 +- Makefile.Pi.Adafruit | 2 +- Makefile.Pi.HD44780 | 2 +- Makefile.Pi.OLED | 2 +- Makefile.Pi.PCF8574 | 2 +- Makefile.Solaris | 2 +- RemoteControl.cpp | 60 +++++++++++++++++++++++++++++++++++++++ RemoteControl.h | 44 ++++++++++++++++++++++++++++ 15 files changed, 187 insertions(+), 12 deletions(-) create mode 100644 RemoteControl.cpp create mode 100644 RemoteControl.h diff --git a/Conf.cpp b/Conf.cpp index 1695f3f..dff7303 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015-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 @@ -56,7 +56,8 @@ enum SECTION { SECTION_OLED, SECTION_LCDPROC, SECTION_LOCK_FILE, - SECTION_MOBILE_GPS + SECTION_MOBILE_GPS, + SECTION_REMOTE_CONTROL }; CConf::CConf(const std::string& file) : @@ -246,7 +247,9 @@ m_lockFileEnabled(false), m_lockFileName(), m_mobileGPSEnabled(false), m_mobileGPSAddress(), -m_mobileGPSPort(0U) +m_mobileGPSPort(0U), +m_remoteControlEnabled(false), +m_remoteControlPort(0U) { } @@ -326,6 +329,8 @@ bool CConf::read() section = SECTION_LOCK_FILE; else if (::strncmp(buffer, "[Mobile GPS]", 12U) == 0) section = SECTION_MOBILE_GPS; + else if (::strncmp(buffer, "[Remote Control]", 16U) == 0) + section = SECTION_REMOTE_CONTROL; else section = SECTION_NONE; @@ -813,6 +818,11 @@ bool CConf::read() m_mobileGPSAddress = value; else if (::strcmp(key, "Port") == 0) m_mobileGPSPort = (unsigned int)::atoi(value); + } else if (section == SECTION_REMOTE_CONTROL) { + if (::strcmp(key, "Enable") == 0) + m_remoteControlEnabled = ::atoi(value) == 1; + else if (::strcmp(key, "Port") == 0) + m_remoteControlPort = (unsigned int)::atoi(value); } } @@ -1756,3 +1766,12 @@ unsigned int CConf::getMobileGPSPort() const return m_mobileGPSPort; } +bool CConf::getRemoteControlEnabled() const +{ + return m_remoteControlEnabled; +} + +unsigned int CConf::getRemoteControlPort() const +{ + return m_remoteControlPort; +} diff --git a/Conf.h b/Conf.h index c3a2d38..32ea085 100644 --- a/Conf.h +++ b/Conf.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015-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 @@ -273,6 +273,10 @@ public: std::string getMobileGPSAddress() const; unsigned int getMobileGPSPort() const; + // The Remote Control section + bool getRemoteControlEnabled() const; + unsigned int getRemoteControlPort() const; + private: std::string m_file; std::string m_callsign; @@ -489,6 +493,9 @@ private: bool m_mobileGPSEnabled; std::string m_mobileGPSAddress; unsigned int m_mobileGPSPort; + + bool m_remoteControlEnabled; + unsigned int m_remoteControlPort; }; #endif diff --git a/MMDVM.ini b/MMDVM.ini index 78d00b3..519cee7 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -252,3 +252,6 @@ Enable=0 Address=127.0.0.1 Port=7834 +[Remote Control] +Enable=0 +Port=7642 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 07df029..1f46391 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015-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 @@ -28,6 +28,7 @@ #include "P25Control.h" #include "NXDNControl.h" #include "POCSAGControl.h" +#include "RemoteControl.h" #include "Thread.h" #include "Log.h" #include "GitVersion.h" @@ -582,6 +583,23 @@ int CMMDVMHost::run() pocsagTimer.start(); } + CRemoteControl* remoteControl = NULL; + bool remoteControlEnabled = m_conf.getRemoteControlEnabled(); + if (remoteControlEnabled) { + unsigned int port = m_conf.getRemoteControlPort(); + + LogInfo("Remote Control Parameters"); + LogInfo(" Port; %u", port); + + remoteControl = new CRemoteControl(port); + + ret = remoteControl->open(); + if (!ret) { + delete remoteControl; + remoteControl = NULL; + } + } + setMode(MODE_IDLE); LogMessage("MMDVMHost-%s is running", VERSION); @@ -908,6 +926,17 @@ int CMMDVMHost::run() m_modem->writeTransparentData(data, len); } + if (remoteControl != NULL) { + REMOTE_COMMAND command = remoteControl->getCommand(); + switch(command) { + case RC_FORCE_IDLE: + setMode(MODE_IDLE); + break; + default: + break; + } + } + unsigned int ms = stopWatch.elapsed(); stopWatch.start(); @@ -1051,6 +1080,11 @@ int CMMDVMHost::run() delete transparentSocket; } + if (remoteControl != NULL) { + remoteControl->close(); + delete remoteControl; + } + delete dstar; delete dmr; delete ysf; diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 9092368..68e7f18 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -220,6 +220,7 @@ + @@ -308,6 +309,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index 0c595bf..641846e 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -65,6 +65,9 @@ Header Files + + Header Files + Header Files @@ -331,6 +334,9 @@ Source Files + + Source Files + Source Files diff --git a/Makefile b/Makefile index 537fa2e..029e359 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ OBJECTS = \ DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o LCDproc.o Log.o MMDVMHost.o MobileGPS.o Modem.o ModemSerialPort.o Mutex.o \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o \ NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o \ - POCSAGControl.o POCSAGNetwork.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o \ + POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o \ Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi b/Makefile.Pi index 2f5de8f..fad658d 100644 --- a/Makefile.Pi +++ b/Makefile.Pi @@ -12,7 +12,7 @@ OBJECTS = \ DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o LCDproc.o Log.o MMDVMHost.o MobileGPS.o Modem.o ModemSerialPort.o Mutex.o \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ - POCSAGNetwork.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o \ + POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o \ UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index fc6df16..ee8122b 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -12,7 +12,7 @@ OBJECTS = \ DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o LCDproc.o Log.o MMDVMHost.o MobileGPS.o Modem.o ModemSerialPort.o Mutex.o \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ - POCSAGNetwork.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index 1246297..a80db42 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -12,7 +12,7 @@ OBJECTS = \ DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o LCDproc.o Log.o MMDVMHost.o MobileGPS.o Modem.o ModemSerialPort.o Mutex.o \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ - POCSAGNetwork.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index 2c45165..71c53aa 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -12,7 +12,7 @@ OBJECTS = \ DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o OLED.o LCDproc.o Log.o MMDVMHost.o MobileGPS.o Modem.o ModemSerialPort.o Mutex.o \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ - POCSAGNetwork.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index 30aaf24..f9dfdb9 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -12,7 +12,7 @@ OBJECTS = \ DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o LCDproc.o Log.o MMDVMHost.o MobileGPS.o Modem.o ModemSerialPort.o Mutex.o \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ - POCSAGNetwork.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Solaris b/Makefile.Solaris index b701271..7c94cea 100644 --- a/Makefile.Solaris +++ b/Makefile.Solaris @@ -12,7 +12,7 @@ OBJECTS = \ DStarSlowData.o Golay2087.o Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o MobileGPS.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o \ NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o \ NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o \ - QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ + QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/RemoteControl.cpp b/RemoteControl.cpp new file mode 100644 index 0000000..e60a2c3 --- /dev/null +++ b/RemoteControl.cpp @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#include "RemoteControl.h" + +#include +#include + +const unsigned int BUFFER_LENGTH = 100U; + +CRemoteControl::CRemoteControl(unsigned int port) : +m_socket(port) +{ + assert(port > 0U); +} + +CRemoteControl::~CRemoteControl() +{ +} + +bool CRemoteControl::open() +{ + return m_socket.open(); +} + +REMOTE_COMMAND CRemoteControl::getCommand() +{ + REMOTE_COMMAND command = RC_NONE; + + unsigned char buffer[BUFFER_LENGTH]; + in_addr address; + unsigned int port; + int ret = m_socket.read(buffer, BUFFER_LENGTH, address, port); + if (ret > 0) { + if (::memcmp(buffer, "0", 1U) == 0) + command = RC_FORCE_IDLE; + } + + return command; +} + +void CRemoteControl::close() +{ + m_socket.close(); +} diff --git a/RemoteControl.h b/RemoteControl.h new file mode 100644 index 0000000..4d0360d --- /dev/null +++ b/RemoteControl.h @@ -0,0 +1,44 @@ +/* + * 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 RemoteControl_H +#define RemoteControl_H + +#include "UDPSocket.h" + +enum REMOTE_COMMAND { + RC_NONE, + RC_FORCE_IDLE +}; + +class CRemoteControl { +public: + CRemoteControl(unsigned int port); + ~CRemoteControl(); + + bool open(); + + REMOTE_COMMAND getCommand(); + + void close(); + +private: + CUDPSocket m_socket; +}; + +#endif