Skip to content

Commit

Permalink
SimplePTT GPIO amd commands: finalization
Browse files Browse the repository at this point in the history
  • Loading branch information
f4exb committed May 29, 2023
1 parent c50c975 commit 0cf88e8
Show file tree
Hide file tree
Showing 12 changed files with 690 additions and 24 deletions.
5 changes: 4 additions & 1 deletion plugins/feature/simpleptt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ if(NOT SERVER_MODE)
${simpleptt_SOURCES}
simplepttgui.cpp
simplepttgui.ui
simplepttcommandoutputdialog.cpp
simplepttcommandoutputdialog.ui
)
set(simpleptt_HEADERS
${simpleptt_HEADERS}
simplepttgui.h
)
simplepttcommandoutputdialog.h
)

set(TARGET_NAME featuresimpleptt)
set(TARGET_LIB "Qt::Widgets")
Expand Down
88 changes: 88 additions & 0 deletions plugins/feature/simpleptt/simpleptt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,28 @@ void SimplePTT::webapiFormatFeatureSettings(
response.getSimplePttSettings()->setVoxEnable(settings.m_voxEnable ? 1 : 0);
response.getSimplePttSettings()->setVoxHold(settings.m_voxHold);
response.getSimplePttSettings()->setVoxLevel(settings.m_voxLevel);
response.getSimplePttSettings()->setGpioControl((int) settings.m_gpioControl);
response.getSimplePttSettings()->setRx2txGpioEnable(settings.m_rx2txGPIOEnable ? 1 : 0);
response.getSimplePttSettings()->setRx2txGpioMask(settings.m_rx2txGPIOMask);
response.getSimplePttSettings()->setRx2txGpioValues(settings.m_rx2txGPIOValues);
response.getSimplePttSettings()->setRx2txCommandEnable(settings.m_rx2txCommandEnable ? 1 : 0);

if (response.getSimplePttSettings()->getRx2txCommand()) {
*response.getSimplePttSettings()->getRx2txCommand() = settings.m_rx2txCommand;
} else {
response.getSimplePttSettings()->setRx2txCommand(new QString(settings.m_rx2txCommand));
}

response.getSimplePttSettings()->setTx2rxGpioEnable(settings.m_tx2rxGPIOEnable ? 1 : 0);
response.getSimplePttSettings()->setTx2rxGpioMask(settings.m_tx2rxGPIOMask);
response.getSimplePttSettings()->setTx2rxGpioValues(settings.m_tx2rxGPIOValues);
response.getSimplePttSettings()->setTx2rxCommandEnable(settings.m_tx2rxCommandEnable ? 1 : 0);

if (response.getSimplePttSettings()->getTx2rxCommand()) {
*response.getSimplePttSettings()->getTx2rxCommand() = settings.m_tx2rxCommand;
} else {
response.getSimplePttSettings()->setTx2rxCommand(new QString(settings.m_tx2rxCommand));
}

response.getSimplePttSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);

Expand Down Expand Up @@ -421,6 +443,39 @@ void SimplePTT::webapiUpdateFeatureSettings(
if (featureSettingsKeys.contains("voxLevel")) {
settings.m_voxLevel = response.getSimplePttSettings()->getVoxLevel();
}
if (featureSettingsKeys.contains("gpioControl")) {
settings.m_gpioControl = (SimplePTTSettings::GPIOControl) response.getSimplePttSettings()->getGpioControl();
}
if (featureSettingsKeys.contains("rx2txGPIOEnable")) {
settings.m_rx2txGPIOEnable = response.getSimplePttSettings()->getRx2txGpioEnable() != 0;
}
if (featureSettingsKeys.contains("rx2txGPIOMask")) {
settings.m_rx2txGPIOMask = response.getSimplePttSettings()->getRx2txGpioMask();
}
if (featureSettingsKeys.contains("rx2txGPIOValues")) {
settings.m_rx2txGPIOValues = response.getSimplePttSettings()->getRx2txGpioValues();
}
if (featureSettingsKeys.contains("rx2txGPIOEnable")) {
settings.m_rx2txCommandEnable = response.getSimplePttSettings()->getRx2txCommandEnable() != 0;
}
if (featureSettingsKeys.contains("rx2txCommand")) {
settings.m_rx2txCommand = *response.getSimplePttSettings()->getRx2txCommand();
}
if (featureSettingsKeys.contains("tx2rxGPIOEnable")) {
settings.m_tx2rxGPIOEnable = response.getSimplePttSettings()->getTx2rxGpioEnable() != 0;
}
if (featureSettingsKeys.contains("tx2rxGPIOMask")) {
settings.m_tx2rxGPIOMask = response.getSimplePttSettings()->getTx2rxGpioMask();
}
if (featureSettingsKeys.contains("tx2rxGPIOValues")) {
settings.m_tx2rxGPIOValues = response.getSimplePttSettings()->getTx2rxGpioValues();
}
if (featureSettingsKeys.contains("tx2rxGPIOEnable")) {
settings.m_tx2rxCommandEnable = response.getSimplePttSettings()->getTx2rxCommandEnable() != 0;
}
if (featureSettingsKeys.contains("tx2rxCommand")) {
settings.m_tx2rxCommand = *response.getSimplePttSettings()->getTx2rxCommand();
}
if (featureSettingsKeys.contains("useReverseAPI")) {
settings.m_useReverseAPI = response.getSimplePttSettings()->getUseReverseApi() != 0;
}
Expand Down Expand Up @@ -488,6 +543,39 @@ void SimplePTT::webapiReverseSendSettings(const QList<QString>& channelSettingsK
if (channelSettingsKeys.contains("voxLevel") || force) {
swgSimplePTTSettings->setVoxLevel(settings.m_voxLevel);
}
if (channelSettingsKeys.contains("gpioControl") || force) {
swgSimplePTTSettings->setGpioControl((int) settings.m_gpioControl);
}
if (channelSettingsKeys.contains("rx2txGPIOEnable") || force) {
swgSimplePTTSettings->setRx2txGpioEnable(settings.m_rx2txGPIOEnable ? 1 : 0);
}
if (channelSettingsKeys.contains("rx2txGPIOMask") || force) {
swgSimplePTTSettings->setRx2txGpioMask(settings.m_rx2txGPIOMask);
}
if (channelSettingsKeys.contains("rx2txGPIOValues") || force) {
swgSimplePTTSettings->setRx2txGpioValues(settings.m_rx2txGPIOValues);
}
if (channelSettingsKeys.contains("rx2txCommandEnable") || force) {
swgSimplePTTSettings->setRx2txCommandEnable(settings.m_rx2txCommandEnable ? 1 : 0);
}
if (channelSettingsKeys.contains("rx2txCommand") || force) {
swgSimplePTTSettings->setRx2txCommand(new QString(settings.m_rx2txCommand));
}
if (channelSettingsKeys.contains("tx2rxGPIOEnable") || force) {
swgSimplePTTSettings->setTx2rxGpioEnable(settings.m_tx2rxGPIOEnable ? 1 : 0);
}
if (channelSettingsKeys.contains("t2rxGPIOMask") || force) {
swgSimplePTTSettings->setTx2rxGpioMask(settings.m_tx2rxGPIOMask);
}
if (channelSettingsKeys.contains("tx2rxGPIOValues") || force) {
swgSimplePTTSettings->setTx2rxGpioValues(settings.m_tx2rxGPIOValues);
}
if (channelSettingsKeys.contains("tx2rxCommandEnable") || force) {
swgSimplePTTSettings->setTx2rxCommandEnable(settings.m_tx2rxCommandEnable ? 1 : 0);
}
if (channelSettingsKeys.contains("tx2rxCommand") || force) {
swgSimplePTTSettings->setTx2rxCommand(new QString(settings.m_tx2rxCommand));
}

QString channelSettingsURL = QString("http://%1:%2/sdrangel/featureset/%3/feature/%4/settings")
.arg(settings.m_reverseAPIAddress)
Expand Down
33 changes: 31 additions & 2 deletions plugins/feature/simpleptt/simplepttcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "simplepttmessages.h"
#include "simplepttcommand.h"

MESSAGE_CLASS_DEFINITION(SimplePTTCommand::MsgRun, Message)

SimplePTTCommand::SimplePTTCommand() :
m_currentProcess(nullptr),
m_currentProcessPid(0),
Expand All @@ -33,6 +35,7 @@ SimplePTTCommand::SimplePTTCommand() :
{
m_currentProcessStartTimeStampms = 0;
m_currentProcessFinishTimeStampms = 0;
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
}

SimplePTTCommand::~SimplePTTCommand()
Expand Down Expand Up @@ -95,10 +98,9 @@ void SimplePTTCommand::processError(QProcess::ProcessError error)
}
}


void SimplePTTCommand::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
//qDebug("Command::processFinished: (%d) %d", exitCode, exitStatus);
qDebug("SimplePTTCommand::processFinished: (%d) %d", exitCode, exitStatus);
m_currentProcessFinishTimeStampms = TimeUtil::nowms();
m_currentProcessExitCode = exitCode;
m_currentProcessExitStatus = exitStatus;
Expand Down Expand Up @@ -134,6 +136,8 @@ void SimplePTTCommand::run(const QString& command, int rxDeviceSetIndex, double
return;
}

qDebug("SimplePTTCommand::run: %s", qPrintable(command));

m_currentProcess = new QProcess(this);
m_isInError = false;
m_hasExited = false;
Expand All @@ -156,3 +160,28 @@ void SimplePTTCommand::run(const QString& command, int rxDeviceSetIndex, double
#endif
m_currentProcess->start(command, allArgs);
}

void SimplePTTCommand::handleInputMessages()
{
Message* message;

while ((message = m_inputMessageQueue.pop()))
{
if (handleMessage(*message)) {
delete message;
}
}
}

bool SimplePTTCommand::handleMessage(const Message& message)
{
if (MsgRun::match(message))
{
qDebug("SimplePTTCommand::handleMessage: MsgRun");
const MsgRun& cmd = (const MsgRun&) message;
run(cmd.getCommand(), cmd.getRxDeviceSetIndex(), cmd.getRxCenterFrequency(), cmd.getTxDeviceSetIndex(), cmd.getTxCenterFrequency());
return true;
}

return false;
}
41 changes: 39 additions & 2 deletions plugins/feature/simpleptt/simplepttcommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,49 @@
#include <QObject>
#include <QProcess>

class MessageQueue;
#include "util/message.h"
#include "util/messagequeue.h"

class SimplePTTCommand : public QObject
{
Q_OBJECT
public:
class MsgRun : public Message
{
MESSAGE_CLASS_DECLARATION
public:
const QString& getCommand() const { return m_command; }
int getRxDeviceSetIndex() const { return m_rxDeviceSetIndex; }
double getRxCenterFrequency() const { return m_rxCenterFrequency; }
int getTxDeviceSetIndex() const { return m_txDeviceSetIndex; }
double getTxCenterFrequency() const { return m_txCenterFrequency; }

static MsgRun* create(const QString& command, int rxDeviceSetIndex, double rxCenterFrequency, int txDeviceSetIndex, double txCenterFrequency) {
return new MsgRun(command, rxDeviceSetIndex, rxCenterFrequency, txDeviceSetIndex, txCenterFrequency);
}

private:
QString m_command;
int m_rxDeviceSetIndex;
double m_rxCenterFrequency;
int m_txDeviceSetIndex;
double m_txCenterFrequency;

MsgRun(const QString& command, int rxDeviceSetIndex, double rxCenterFrequency, int txDeviceSetIndex, double txCenterFrequency) :
Message(),
m_command(command),
m_rxDeviceSetIndex(rxDeviceSetIndex),
m_rxCenterFrequency(rxCenterFrequency),
m_txDeviceSetIndex(txDeviceSetIndex),
m_txCenterFrequency(txCenterFrequency)
{ }
};

SimplePTTCommand();
~SimplePTTCommand();
void setMessageQueueToGUI(MessageQueue *messageQueue) { m_msgQueueToGUI = messageQueue; }
void run(const QString& command, int rxDeviceSetIndex, double rxCenterFrequency, int txDeviceSetIndex, double txCenterFrequency);
const QString& getLastLog() { return m_log; }
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }

private:
QProcess *m_currentProcess;
Expand All @@ -45,11 +77,16 @@ class SimplePTTCommand : public QObject
QProcess::ExitStatus m_currentProcessExitStatus;
bool m_hasExited;
MessageQueue *m_msgQueueToGUI; //!< Queue to report state to GUI
MessageQueue m_inputMessageQueue;

bool handleMessage(const Message& message);
void run(const QString& command, int rxDeviceSetIndex, double rxCenterFrequency, int txDeviceSetIndex, double txCenterFrequency);

private slots:
void processStateChanged(QProcess::ProcessState newState);
void processError(QProcess::ProcessError error);
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
void handleInputMessages();
};

#endif // INCLUDE_FEATURE_SIMPLEPTTCOMMAND_H_
113 changes: 113 additions & 0 deletions plugins/feature/simpleptt/simplepttcommandoutputdialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
// //
// 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 as version 3 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////

#include "simplepttcommandoutputdialog.h"
#include "ui_simplepttcommandoutputdialog.h"
#include "simplepttcommand.h"

#include <QDateTime>

SimplePTTCommandOutputDialog::SimplePTTCommandOutputDialog(QWidget* parent) :
QDialog(parent),
ui(new Ui::SimplePTTCommandOutputDialog)
{
ui->setupUi(this);
setStatusIndicator(StatusIndicatorUnknown);
}

SimplePTTCommandOutputDialog::~SimplePTTCommandOutputDialog()
{
delete ui;
}

void SimplePTTCommandOutputDialog::setErrorText(const QProcess::ProcessError& processError)
{
switch(processError)
{
case QProcess::FailedToStart:
ui->errorText->setText("Failed to start");
break;
case QProcess::Crashed:
ui->errorText->setText("Crashed");
break;
case QProcess::Timedout:
ui->errorText->setText("Timed out");
break;
case QProcess::WriteError:
ui->errorText->setText("Write error");
break;
case QProcess::ReadError:
ui->errorText->setText("Read error");
break;
case QProcess::UnknownError:
default:
ui->errorText->setText("No or unknown error");
break;
}
}

void SimplePTTCommandOutputDialog::setExitText(const QProcess::ExitStatus& processExit)
{
switch(processExit)
{
case QProcess::NormalExit:
ui->exitText->setText("Normal exit");
break;
case QProcess::CrashExit:
ui->exitText->setText("Program crashed");
break;
default:
ui->exitText->setText("Unknown state");
break;
}
}

void SimplePTTCommandOutputDialog::setExitCode(int exitCode)
{
ui->exitCode->setText(tr("%1").arg(exitCode));
}

void SimplePTTCommandOutputDialog::setLog(const QString& log)
{
ui->logEdit->setPlainText(log);
}

void SimplePTTCommandOutputDialog::setStatusIndicator(StatusIndicator indicator)
{
QString statusColor;

switch (indicator)
{
case StatusIndicatorOK:
statusColor = "rgb(85, 232, 85)";
break;
case StatusIndicatorKO:
statusColor = "rgb(232, 85, 85)";
break;
default:
statusColor = "gray";
}

ui->statusIndicator->setStyleSheet("QLabel { background-color: " +
statusColor + "; border-radius: 12px; }");
}

void SimplePTTCommandOutputDialog::setEndTime(const QDateTime& dt)
{
QString dateStr = dt.toString("yyyy-MM-dd HH:mm:ss.zzz");
ui->endTime->setText(dateStr);
}
Loading

0 comments on commit 0cf88e8

Please sign in to comment.