From 60cc911ac34e5055c26a4302e31bee64b9d8bf8f Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 27 Oct 2020 11:34:50 +0000 Subject: [PATCH] Reinstate the remote command handler. --- NXDNGateway/Conf.cpp | 24 +++++++++- NXDNGateway/Conf.h | 7 +++ NXDNGateway/NXDNGateway.cpp | 95 +++++++++++++++++++++++++++++++++++++ NXDNGateway/NXDNGateway.ini | 4 ++ 4 files changed, 128 insertions(+), 2 deletions(-) diff --git a/NXDNGateway/Conf.cpp b/NXDNGateway/Conf.cpp index 63117d9..a134377 100644 --- a/NXDNGateway/Conf.cpp +++ b/NXDNGateway/Conf.cpp @@ -35,7 +35,8 @@ enum SECTION { SECTION_LOG, SECTION_APRS, SECTION_NETWORK, - SECTION_GPSD + SECTION_GPSD, + SECTION_REMOTE_COMMANDS }; CConf::CConf(const std::string& file) : @@ -84,7 +85,9 @@ m_networkNetHangTime(60U), m_networkDebug(false), m_gpsdEnabled(false), m_gpsdAddress(), -m_gpsdPort() +m_gpsdPort(), +m_remoteCommandsEnabled(false), +m_remoteCommandsPort(6075U) { } @@ -124,6 +127,8 @@ bool CConf::read() section = SECTION_NETWORK; else if (::strncmp(buffer, "[GPSD]", 6U) == 0) section = SECTION_GPSD; + else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0) + section = SECTION_REMOTE_COMMANDS; else section = SECTION_NONE; @@ -264,6 +269,11 @@ bool CConf::read() m_gpsdAddress = value; else if (::strcmp(key, "Port") == 0) m_gpsdPort = value; + } else if (section == SECTION_REMOTE_COMMANDS) { + if (::strcmp(key, "Enable") == 0) + m_remoteCommandsEnabled = ::atoi(value) == 1; + else if (::strcmp(key, "Port") == 0) + m_remoteCommandsPort = (unsigned int)::atoi(value); } } @@ -496,3 +506,13 @@ std::string CConf::getGPSDPort() const { return m_gpsdPort; } + +bool CConf::getRemoteCommandsEnabled() const +{ + return m_remoteCommandsEnabled; +} + +unsigned int CConf::getRemoteCommandsPort() const +{ + return m_remoteCommandsPort; +} diff --git a/NXDNGateway/Conf.h b/NXDNGateway/Conf.h index 1d97c79..57df9f2 100644 --- a/NXDNGateway/Conf.h +++ b/NXDNGateway/Conf.h @@ -91,6 +91,10 @@ public: std::string getGPSDAddress() const; std::string getGPSDPort() const; + // The Remote Commands section + bool getRemoteCommandsEnabled() const; + unsigned int getRemoteCommandsPort() const; + private: std::string m_file; std::string m_callsign; @@ -145,6 +149,9 @@ private: bool m_gpsdEnabled; std::string m_gpsdAddress; std::string m_gpsdPort; + + bool m_remoteCommandsEnabled; + unsigned int m_remoteCommandsPort; }; #endif diff --git a/NXDNGateway/NXDNGateway.cpp b/NXDNGateway/NXDNGateway.cpp index 12eaf68..dde6e95 100644 --- a/NXDNGateway/NXDNGateway.cpp +++ b/NXDNGateway/NXDNGateway.cpp @@ -216,6 +216,16 @@ void CNXDNGateway::run() return; } + CUDPSocket* remoteSocket = NULL; + if (m_conf.getRemoteCommandsEnabled()) { + remoteSocket = new CUDPSocket(m_conf.getRemoteCommandsPort()); + ret = remoteSocket->open(); + if (!ret) { + delete remoteSocket; + remoteSocket = NULL; + } + } + CReflectors reflectors(m_conf.getNetworkHosts1(), m_conf.getNetworkHosts2(), m_conf.getNetworkReloadTime()); if (m_conf.getNetworkParrotPort() > 0U) reflectors.setParrot(m_conf.getNetworkParrotAddress(), m_conf.getNetworkParrotPort()); @@ -402,6 +412,8 @@ void CNXDNGateway::run() hangTimer.setTimeout(rfHangTime); hangTimer.start(); + } else { + hangTimer.stop(); } if (voice != NULL) { @@ -455,6 +467,84 @@ void CNXDNGateway::run() localNetwork->write(buffer, length); } + if (remoteSocket != NULL) { + sockaddr_storage addr; + unsigned int addrLen; + int res = remoteSocket->read(buffer, 200U, addr, addrLen); + if (res > 0) { + buffer[res] = '\0'; + if (::memcmp(buffer + 0U, "TalkGroup", 9U) == 0) { + unsigned int tg = (unsigned int)::atoi((char*)(buffer + 9U)); + + if (tg != currentTG) { + if (currentAddrLen > 0U) { + LogMessage("Unlinked from reflector %u by remote command", currentTG); + + if (!currentIsStatic) { + remoteNetwork.writeUnlink(currentAddr, currentAddrLen, currentTG); + remoteNetwork.writeUnlink(currentAddr, currentAddrLen, currentTG); + remoteNetwork.writeUnlink(currentAddr, currentAddrLen, currentTG); + } + + hangTimer.stop(); + } + + const CStaticTG* found = NULL; + for (std::vector::const_iterator it = staticTGs.cbegin(); it != staticTGs.cend(); ++it) { + if (tg == (*it).m_tg) { + found = &(*it); + break; + } + } + + if (found == NULL) { + CNXDNReflector* refl = reflectors.find(tg); + if (refl != NULL) { + currentTG = tg; + currentAddr = refl->m_addr; + currentAddrLen = refl->m_addrLen; + currentIsStatic = false; + } else { + currentTG = tg; + currentAddrLen = 0U; + currentIsStatic = false; + } + } else { + currentTG = found->m_tg; + currentAddr = found->m_addr; + currentAddrLen = found->m_addrLen; + currentIsStatic = true; + } + + // Link to the new reflector + if (currentAddrLen > 0U) { + LogMessage("Switched to reflector %u by remote command", currentTG); + + if (!currentIsStatic) { + remoteNetwork.writePoll(currentAddr, currentAddrLen, currentTG); + remoteNetwork.writePoll(currentAddr, currentAddrLen, currentTG); + remoteNetwork.writePoll(currentAddr, currentAddrLen, currentTG); + } + + hangTimer.setTimeout(rfHangTime); + hangTimer.start(); + } else { + hangTimer.stop(); + } + + if (voice != NULL) { + if (currentAddrLen == 0U) + voice->unlinked(); + else + voice->linkedTo(currentTG); + } + } + } else { + CUtils::dump("Invalid remote command received", buffer, res); + } + } + } + unsigned int ms = stopWatch.elapsed(); stopWatch.start(); @@ -512,6 +602,11 @@ void CNXDNGateway::run() localNetwork->close(); delete localNetwork; + if (remoteSocket != NULL) { + remoteSocket->close(); + delete remoteSocket; + } + remoteNetwork.close(); lookup->stop(); diff --git a/NXDNGateway/NXDNGateway.ini b/NXDNGateway/NXDNGateway.ini index 2fb36ac..33bae16 100644 --- a/NXDNGateway/NXDNGateway.ini +++ b/NXDNGateway/NXDNGateway.ini @@ -70,3 +70,7 @@ Debug=0 Enable=0 Address=127.0.0.1 Port=2947 + +[Remote Commands] +Enable=0 +Port=6075