Make the remote command handler more flexible and add an optional

timeout to the new mode.
This commit is contained in:
Jonathan Naylor 2019-01-22 13:40:02 +00:00
parent 8ae8894d6f
commit b57d42327a
3 changed files with 145 additions and 29 deletions

View file

@ -1788,30 +1788,62 @@ void CMMDVMHost::remoteControl()
if (m_mode != MODE_IDLE) if (m_mode != MODE_IDLE)
setMode(MODE_IDLE); setMode(MODE_IDLE);
break; break;
case RCD_MODE_LOCKOUT: case RCD_MODE_LOCKOUT:
if (m_mode != MODE_LOCKOUT) if (m_mode != MODE_LOCKOUT)
setMode(MODE_LOCKOUT); setMode(MODE_LOCKOUT);
break; break;
case RCD_MODE_DSTAR: case RCD_MODE_DSTAR:
if (m_dstar != NULL && m_mode != MODE_DSTAR) if (m_dstar != NULL && m_mode != MODE_DSTAR) {
if (m_remoteControl->getArgCount() > 0U)
m_modeTimer.setTimeout(m_remoteControl->getArgUInt(0U));
else
m_modeTimer.setTimeout(m_dstarRFModeHang);
setMode(MODE_DSTAR); setMode(MODE_DSTAR);
}
break; break;
case RCD_MODE_DMR: case RCD_MODE_DMR:
if (m_dmr != NULL && m_mode != MODE_DMR) if (m_dmr != NULL && m_mode != MODE_DMR) {
if (m_remoteControl->getArgCount() > 0U)
m_modeTimer.setTimeout(m_remoteControl->getArgUInt(0U));
else
m_modeTimer.setTimeout(m_dmrRFModeHang);
setMode(MODE_DMR); setMode(MODE_DMR);
}
break; break;
case RCD_MODE_YSF: case RCD_MODE_YSF:
if (m_ysf != NULL && m_mode != MODE_YSF) if (m_ysf != NULL && m_mode != MODE_YSF) {
if (m_remoteControl->getArgCount() > 0U)
m_modeTimer.setTimeout(m_remoteControl->getArgUInt(0U));
else
m_modeTimer.setTimeout(m_ysfRFModeHang);
setMode(MODE_YSF); setMode(MODE_YSF);
}
break; break;
case RCD_MODE_P25: case RCD_MODE_P25:
if (m_p25 != NULL && m_mode != MODE_P25) if (m_p25 != NULL && m_mode != MODE_P25) {
if (m_remoteControl->getArgCount() > 0U)
m_modeTimer.setTimeout(m_remoteControl->getArgUInt(0U));
else
m_modeTimer.setTimeout(m_p25RFModeHang);
setMode(MODE_P25); setMode(MODE_P25);
}
break; break;
case RCD_MODE_NXDN: case RCD_MODE_NXDN:
if (m_nxdn != NULL && m_mode != MODE_NXDN) if (m_nxdn != NULL && m_mode != MODE_NXDN) {
if (m_remoteControl->getArgCount() > 0U)
m_modeTimer.setTimeout(m_remoteControl->getArgUInt(0U));
else
m_modeTimer.setTimeout(m_nxdnRFModeHang);
setMode(MODE_NXDN); setMode(MODE_NXDN);
}
break; break;
default: default:
break; break;
} }

View file

@ -20,13 +20,18 @@
#include "Log.h" #include "Log.h"
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
const unsigned int SET_MODE_ARGS = 2U;
const unsigned int BUFFER_LENGTH = 100U; const unsigned int BUFFER_LENGTH = 100U;
CRemoteControl::CRemoteControl(unsigned int port) : CRemoteControl::CRemoteControl(unsigned int port) :
m_socket(port) m_socket(port),
m_command(RCD_NONE),
m_args()
{ {
assert(port > 0U); assert(port > 0U);
} }
@ -42,35 +47,103 @@ bool CRemoteControl::open()
REMOTE_COMMAND CRemoteControl::getCommand() REMOTE_COMMAND CRemoteControl::getCommand()
{ {
REMOTE_COMMAND command = RCD_NONE; m_command = RCD_NONE;
m_args.clear();
unsigned char buffer[BUFFER_LENGTH]; char command[BUFFER_LENGTH];
char buffer[BUFFER_LENGTH];
in_addr address; in_addr address;
unsigned int port; unsigned int port;
int ret = m_socket.read(buffer, BUFFER_LENGTH, address, port); int ret = m_socket.read((unsigned char*)buffer, BUFFER_LENGTH, address, port);
if (ret > 0) { if (ret > 0) {
if (ret == 9 && ::memcmp(buffer, "mode idle", 9U) == 0) buffer[ret] = '\0';
command = RCD_MODE_IDLE;
else if (ret == 12 && ::memcmp(buffer, "mode lockout", 12U) == 0)
command = RCD_MODE_LOCKOUT;
else if (ret == 11 && ::memcmp(buffer, "mode d-star", 11U) == 0)
command = RCD_MODE_DSTAR;
else if (ret == 8 && ::memcmp(buffer, "mode dmr", 8U) == 0)
command = RCD_MODE_DMR;
else if (ret == 8 && ::memcmp(buffer, "mode ysf", 8U) == 0)
command = RCD_MODE_YSF;
else if (ret == 8 && ::memcmp(buffer, "mode p25", 8U) == 0)
command = RCD_MODE_P25;
else if (ret == 9 && ::memcmp(buffer, "mode nxdn", 9U) == 0)
command = RCD_MODE_NXDN;
if (command == RCD_NONE) // Make a copy of the original command for logging.
LogWarning("Invalid remote command of \"%.*s\" received", ret, buffer); ::strcpy(command, buffer);
else
LogMessage("Valid remote command of \"%.*s\" received", ret, buffer); // Parse the original command into a vector of strings.
char* b = buffer;
char* p = NULL;
while ((p = ::strtok(b, " ")) != NULL) {
b = NULL;
m_args.push_back(std::string(p));
}
if (m_args.at(0U) == "mode" && m_args.length() >= SET_MODE_ARGS) {
// Mode command is in the form of "mode <mode> [timeout]"
if (m_args.at(1U) == "idle")
m_command = RCD_MODE_IDLE;
else if (m_args.at(1U) == "lockout")
m_command = RCD_MODE_LOCKOUT;
else if (m_args.at(1U) == "d-star")
m_command = RCD_MODE_DSTAR;
else if (m_args.at(1U) == "dmr")
m_command = RCD_MODE_DMR;
else if (m_args.at(1U) == "ysf")
m_command = RCD_MODE_YSF;
else if (m_args.at(1U) == "p25")
m_command = RCD_MODE_P25;
else if (m_args.at(1U) == "nxdn")
m_command = RCD_MODE_NXDN;
}
if (m_command == RCD_NONE) {
m_args.clear();
LogWarning("Invalid remote command of \"%s\" received", command);
} else {
LogMessage("Valid remote command of \"%s\" received", command);
}
} }
return command; return m_command;
}
unsigned int CRemoteControl::getArgCount() const
{
switch (m_command) {
case RCD_MODE_IDLE:
case RCD_MODE_LOCKOUT:
case RCD_MODE_DSTAR:
case RCD_MODE_DMR:
case RCD_MODE_YSF:
case RCD_MODE_P25:
case RCD_MODE_NXDN:
return m_args.length() - SET_MODE_ARGS;
default:
return 0U;
}
}
std::string CRemoteControl::getArgString(unsigned int n) const
{
switch (m_command) {
case RCD_MODE_IDLE:
case RCD_MODE_LOCKOUT:
case RCD_MODE_DSTAR:
case RCD_MODE_DMR:
case RCD_MODE_YSF:
case RCD_MODE_P25:
case RCD_MODE_NXDN:
n += SET_MODE_ARGS;
break;
default:
return "";
}
if (n >= m_args.length())
return "";
return m_args.at(n);
}
unsigned int CRemoteControl::getArgUInt(unsigned int n) const
{
return (unsigned int)::atoi(getArgString(n).c_str());
}
int CRemoteControl::getArgInt(unsigned int n) const
{
return ::atoi(getArgString(n).c_str());
} }
void CRemoteControl::close() void CRemoteControl::close()

View file

@ -21,6 +21,9 @@
#include "UDPSocket.h" #include "UDPSocket.h"
#include <vector>
#include <string>
enum REMOTE_COMMAND { enum REMOTE_COMMAND {
RCD_NONE, RCD_NONE,
RCD_MODE_IDLE, RCD_MODE_IDLE,
@ -41,10 +44,18 @@ public:
REMOTE_COMMAND getCommand(); REMOTE_COMMAND getCommand();
unsigned int getArgCount() const;
std::string getArgString(unsigned int n) const;
unsigned int getArgUInt(unsigned int n) const;
signed int getArgInt(unsigned int n) const;
void close(); void close();
private: private:
CUDPSocket m_socket; CUDPSocket m_socket;
REMOTE_COMMAND m_command;
std::vector<std::string> m_args;
}; };
#endif #endif