diff --git a/plugins/feature/simpleptt/CMakeLists.txt b/plugins/feature/simpleptt/CMakeLists.txt index 64ff045d0..a4caa3c57 100644 --- a/plugins/feature/simpleptt/CMakeLists.txt +++ b/plugins/feature/simpleptt/CMakeLists.txt @@ -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") diff --git a/plugins/feature/simpleptt/simpleptt.cpp b/plugins/feature/simpleptt/simpleptt.cpp index ebf61f63b..f0f6e7bb2 100644 --- a/plugins/feature/simpleptt/simpleptt.cpp +++ b/plugins/feature/simpleptt/simpleptt.cpp @@ -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); @@ -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; } @@ -488,6 +543,39 @@ void SimplePTT::webapiReverseSendSettings(const QList& 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) diff --git a/plugins/feature/simpleptt/simplepttcommand.cpp b/plugins/feature/simpleptt/simplepttcommand.cpp index d1dc2e010..1efb518c4 100644 --- a/plugins/feature/simpleptt/simplepttcommand.cpp +++ b/plugins/feature/simpleptt/simplepttcommand.cpp @@ -20,6 +20,8 @@ #include "simplepttmessages.h" #include "simplepttcommand.h" +MESSAGE_CLASS_DEFINITION(SimplePTTCommand::MsgRun, Message) + SimplePTTCommand::SimplePTTCommand() : m_currentProcess(nullptr), m_currentProcessPid(0), @@ -33,6 +35,7 @@ SimplePTTCommand::SimplePTTCommand() : { m_currentProcessStartTimeStampms = 0; m_currentProcessFinishTimeStampms = 0; + connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); } SimplePTTCommand::~SimplePTTCommand() @@ -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; @@ -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; @@ -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; +} diff --git a/plugins/feature/simpleptt/simplepttcommand.h b/plugins/feature/simpleptt/simplepttcommand.h index 881031711..c4b5a86df 100644 --- a/plugins/feature/simpleptt/simplepttcommand.h +++ b/plugins/feature/simpleptt/simplepttcommand.h @@ -20,17 +20,49 @@ #include #include -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; @@ -45,11 +77,16 @@ private: 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_ diff --git a/plugins/feature/simpleptt/simplepttcommandoutputdialog.cpp b/plugins/feature/simpleptt/simplepttcommandoutputdialog.cpp new file mode 100644 index 000000000..19adea6dc --- /dev/null +++ b/plugins/feature/simpleptt/simplepttcommandoutputdialog.cpp @@ -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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "simplepttcommandoutputdialog.h" +#include "ui_simplepttcommandoutputdialog.h" +#include "simplepttcommand.h" + +#include + +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); +} diff --git a/plugins/feature/simpleptt/simplepttcommandoutputdialog.h b/plugins/feature/simpleptt/simplepttcommandoutputdialog.h new file mode 100644 index 000000000..f8cf03ac1 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttcommandoutputdialog.h @@ -0,0 +1,58 @@ +/////////////////////////////////////////////////////////////////////////////////// +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_ +#define SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_ + +#include +#include + +#include "export.h" + +namespace Ui { + class SimplePTTCommandOutputDialog; +} + +class Command; + +class SimplePTTCommandOutputDialog : public QDialog { + Q_OBJECT + +public: + enum StatusIndicator + { + StatusIndicatorUnknown, + StatusIndicatorOK, + StatusIndicatorKO + }; + + explicit SimplePTTCommandOutputDialog(QWidget* parent = 0); + ~SimplePTTCommandOutputDialog(); + void setErrorText(const QProcess::ProcessError& processError); + void setExitText(const QProcess::ExitStatus& processExit); + void setExitCode(int exitCode); + void setLog(const QString& log); + void setStatusIndicator(StatusIndicator indicator); + void setEndTime(const QDateTime& dt); + +private: + Ui::SimplePTTCommandOutputDialog* ui; + +}; + + +#endif /* SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_ */ diff --git a/plugins/feature/simpleptt/simplepttcommandoutputdialog.ui b/plugins/feature/simpleptt/simplepttcommandoutputdialog.ui new file mode 100644 index 000000000..685117fe4 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttcommandoutputdialog.ui @@ -0,0 +1,240 @@ + + + SimplePTTCommandOutputDialog + + + + 0 + 0 + 547 + 380 + + + + + Liberation Sans + 9 + + + + Simple PTT command output + + + + :/sdrangel_icon.png:/sdrangel_icon.png + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + Idle + + + QLabel { background-color: gray; border-radius: 12px; } + + + + + + + + + + + 146 + 0 + + + + + Liberation Sans + 8 + + + + End time of last execution + + + 2015-01-01 00:00:00.000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 23 + + + + Error: + + + + + + + + 0 + 0 + + + + Process error status + + + ... + + + + + + + + 30 + 23 + + + + Exit: + + + + + + + + 0 + 0 + + + + Return code + + + 0 + + + + + + + + 0 + 0 + + + + Process exit status + + + ... + + + + + + + + + true + + + + Monospace + 9 + + + + Output log (stdout + stderr) + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + buttonBox + + + + + + + buttonBox + accepted() + SimplePTTCommandOutputDialog + close() + + + 273 + 357 + + + 273 + 189 + + + + + buttonBox + rejected() + SimplePTTCommandOutputDialog + close() + + + 273 + 357 + + + 273 + 189 + + + + + diff --git a/plugins/feature/simpleptt/simplepttgui.cpp b/plugins/feature/simpleptt/simplepttgui.cpp index ab1323ab3..1ed01e671 100644 --- a/plugins/feature/simpleptt/simplepttgui.cpp +++ b/plugins/feature/simpleptt/simplepttgui.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "feature/featureuiset.h" #include "gui/basicfeaturesettingsdialog.h" @@ -33,6 +34,8 @@ #include "simplepttreport.h" #include "simpleptt.h" #include "simplepttgui.h" +#include "simplepttmessages.h" +#include "simplepttcommandoutputdialog.h" SimplePTTGUI* SimplePTTGUI::create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature) { @@ -127,6 +130,31 @@ bool SimplePTTGUI::handleMessage(const Message& message) return true; } + else if (SimplePTTMessages::MsgCommandError::match(message)) + { + qDebug("SimplePTTGUI::handleMessage: SimplePTTMessages::MsgCommandError"); + SimplePTTMessages::MsgCommandError& report = (SimplePTTMessages::MsgCommandError&) message; + m_lastCommandError = report.getError(); + m_lastCommandLog = report.getLog(); + m_lastCommandEndTime = QDateTime::fromMSecsSinceEpoch(report.getFinishedTimeStamp()); + m_lastCommandErrorReported = true; + m_lastCommandResult = true; + + return true; + } + else if (SimplePTTMessages::MsgCommandFinished::match(message)) + { + qDebug("SimplePTTGUI::handleMessage: SimplePTTMessages::MsgCommandFinished"); + SimplePTTMessages::MsgCommandFinished& report = (SimplePTTMessages::MsgCommandFinished&) message; + m_lastCommandExitCode = report.getExitCode(); + m_lastCommandExitStatus = report.getExitStatus(); + m_lastCommandLog = report.getLog(); + m_lastCommandEndTime = QDateTime::fromMSecsSinceEpoch(report.getFinishedTimeStamp()); + m_lastCommandErrorReported = false; + m_lastCommandResult = true; + + return true; + } return false; } @@ -158,7 +186,12 @@ SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Fea m_pluginAPI(pluginAPI), m_featureUISet(featureUISet), m_doApplySettings(true), - m_lastFeatureState(0) + m_lastFeatureState(0), + m_lastCommandResult(false), + m_lastCommandExitCode(0), + m_lastCommandExitStatus(QProcess::NormalExit), + m_lastCommandError(QProcess::UnknownError), + m_lastCommandErrorReported(false) { m_feature = feature; setAttribute(Qt::WA_DeleteOnClose, true); @@ -604,6 +637,23 @@ void SimplePTTGUI::on_gpioControl_clicked() applySettings(); } +void SimplePTTGUI::on_lastCommandLog_clicked() +{ + if (!m_lastCommandResult) { + return; + } + + SimplePTTCommandOutputDialog commandOutputDialog(this); + commandOutputDialog.setErrorText((QProcess::ProcessError) m_lastCommandError); + commandOutputDialog.setExitText((QProcess::ExitStatus) m_lastCommandExitStatus); + commandOutputDialog.setExitCode(m_lastCommandExitCode); + commandOutputDialog.setLog(m_lastCommandLog); + commandOutputDialog.setStatusIndicator(m_lastCommandErrorReported ? + SimplePTTCommandOutputDialog::StatusIndicatorKO : SimplePTTCommandOutputDialog::StatusIndicatorOK); + commandOutputDialog.setEndTime(m_lastCommandEndTime); + commandOutputDialog.exec(); +} + void SimplePTTGUI::updateStatus() { int state = m_simplePTT->getState(); @@ -702,4 +752,5 @@ void SimplePTTGUI::makeUIConnections() QObject::connect(ui->gpioTxRxValue, &QLineEdit::editingFinished, this, &SimplePTTGUI::on_gpioTxRxValue_editingFinished); QObject::connect(ui->gpioRxControl, &QRadioButton::clicked, this, &SimplePTTGUI::on_gpioControl_clicked); QObject::connect(ui->gpioTxControl, &QRadioButton::clicked, this, &SimplePTTGUI::on_gpioControl_clicked); + QObject::connect(ui->lastCommandLog, &QPushButton::clicked, this, &SimplePTTGUI::on_lastCommandLog_clicked); } diff --git a/plugins/feature/simpleptt/simplepttgui.h b/plugins/feature/simpleptt/simplepttgui.h index abe54264a..38b2048e4 100644 --- a/plugins/feature/simpleptt/simplepttgui.h +++ b/plugins/feature/simpleptt/simplepttgui.h @@ -19,6 +19,7 @@ #define INCLUDE_FEATURE_SIMPLEPTTGUI_H_ #include +#include #include "feature/featuregui.h" #include "util/messagequeue.h" @@ -65,6 +66,14 @@ private: std::vector m_statusColors; std::vector m_statusTooltips; + bool m_lastCommandResult; + int m_lastCommandExitCode; + int m_lastCommandExitStatus; + int m_lastCommandError; + bool m_lastCommandErrorReported; + QDateTime m_lastCommandEndTime; + QString m_lastCommandLog; + explicit SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); virtual ~SimplePTTGUI(); @@ -102,6 +111,7 @@ private slots: void on_gpioTxRxMask_editingFinished(); void on_gpioTxRxValue_editingFinished(); void on_gpioControl_clicked(); + void on_lastCommandLog_clicked(); void updateStatus(); void audioSelect(const QPoint& p); diff --git a/plugins/feature/simpleptt/simplepttgui.ui b/plugins/feature/simpleptt/simplepttgui.ui index 9299f655b..2338dd6ac 100644 --- a/plugins/feature/simpleptt/simplepttgui.ui +++ b/plugins/feature/simpleptt/simplepttgui.ui @@ -362,6 +362,26 @@ + + + + + 24 + 16777215 + + + + Show last command status and log + + + + + + + :/listing.png:/listing.png + + + diff --git a/plugins/feature/simpleptt/simplepttworker.cpp b/plugins/feature/simpleptt/simplepttworker.cpp index 602837f59..8daf13447 100644 --- a/plugins/feature/simpleptt/simplepttworker.cpp +++ b/plugins/feature/simpleptt/simplepttworker.cpp @@ -44,6 +44,7 @@ SimplePTTWorker::SimplePTTWorker(WebAPIAdapterInterface *webAPIAdapterInterface) m_voxState(false), m_updateTimer(this) { + m_audioFifo.setLabel("SimplePTTWorker"); m_audioReadBuffer.resize(16384); m_audioReadBufferFill = 0; qDebug("SimplePTTWorker::SimplePTTWorker"); @@ -124,7 +125,6 @@ void SimplePTTWorker::applySettings(const SimplePTTSettings& settings, const QLi AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName); audioDeviceManager->removeAudioSource(&m_audioFifo); - audioDeviceManager->addAudioSource(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex); m_audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex); m_voxHoldCount = 0; m_voxState = false; @@ -143,10 +143,18 @@ void SimplePTTWorker::applySettings(const SimplePTTSettings& settings, const QLi m_msgQueueToGUI->push(msg); } - if (settings.m_vox) { + AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); + int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName); + + if (settings.m_vox) + { connect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio())); - } else { + audioDeviceManager->addAudioSource(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex); + } + else + { disconnect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio())); + audioDeviceManager->removeAudioSource(&m_audioFifo); } } @@ -165,12 +173,13 @@ void SimplePTTWorker::applySettings(const SimplePTTSettings& settings, const QLi void SimplePTTWorker::sendPTT(bool tx) { qDebug("SimplePTTWorker::sendPTT: %s", tx ? "tx" : "rx"); + if (!m_updateTimer.isActive()) { bool switchedOff = false; m_mutex.lock(); - if (tx) + if (tx) // Rx to Tx { if (m_settings.m_rxDeviceSetIndex >= 0) { @@ -185,7 +194,7 @@ void SimplePTTWorker::sendPTT(bool tx) m_updateTimer.start(m_settings.m_rx2TxDelayMs); } } - else + else // Tx to Rx { if (m_settings.m_txDeviceSetIndex >= 0) { @@ -254,18 +263,25 @@ bool SimplePTTWorker::turnDevice(bool on) void SimplePTTWorker::preSwitch(bool tx) { - double rxFrequency = 0; - double txFrequency = 0; - ChannelWebAPIUtils::getCenterFrequency(m_settings.m_rxDeviceSetIndex, rxFrequency); - ChannelWebAPIUtils::getCenterFrequency(m_settings.m_txDeviceSetIndex, txFrequency); + bool validCommand = tx ? m_settings.m_rx2txCommand.size() > 0 : m_settings.m_tx2rxCommand.size() > 0; - m_command.run( - tx ? m_settings.m_rx2txCommand : m_settings.m_tx2rxCommand, - m_settings.m_rxDeviceSetIndex, - rxFrequency, - m_settings.m_txDeviceSetIndex, - txFrequency - ); + if (validCommand) + { + double rxFrequency = 0; + double txFrequency = 0; + ChannelWebAPIUtils::getCenterFrequency(m_settings.m_rxDeviceSetIndex, rxFrequency); + ChannelWebAPIUtils::getCenterFrequency(m_settings.m_txDeviceSetIndex, txFrequency); + + SimplePTTCommand::MsgRun *msg = SimplePTTCommand::MsgRun::create( + tx ? m_settings.m_rx2txCommand : m_settings.m_tx2rxCommand, + m_settings.m_rxDeviceSetIndex, + rxFrequency, + m_settings.m_txDeviceSetIndex, + txFrequency + ); + + m_command.getInputMessageQueue()->push(msg); + } if (m_settings.m_gpioControl == SimplePTTSettings::GPIONone) { return; diff --git a/plugins/feature/simpleptt/simplepttworker.h b/plugins/feature/simpleptt/simplepttworker.h index cc81cfbdc..17c1e01f2 100644 --- a/plugins/feature/simpleptt/simplepttworker.h +++ b/plugins/feature/simpleptt/simplepttworker.h @@ -86,7 +86,8 @@ public: void stopWork(); MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } - void setMessageQueueToGUI(MessageQueue *messageQueue) { + void setMessageQueueToGUI(MessageQueue *messageQueue) + { m_msgQueueToGUI = messageQueue; m_command.setMessageQueueToGUI(messageQueue); }