SimplePTT GPIO amd commands: finalization

pull/1711/head
f4exb 2023-05-29 08:39:42 +02:00
rodzic c50c9753f6
commit 0cf88e8f35
12 zmienionych plików z 689 dodań i 23 usunięć

Wyświetl plik

@ -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")

Wyświetl plik

@ -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<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)

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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;
@ -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_

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_
#define SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_
#include <QDialog>
#include <QProcess>
#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_ */

Wyświetl plik

@ -0,0 +1,240 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SimplePTTCommandOutputDialog</class>
<widget class="QDialog" name="SimplePTTCommandOutputDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>547</width>
<height>380</height>
</rect>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Simple PTT command output</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>:/sdrangel_icon.png</normaloff>:/sdrangel_icon.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="processLayout">
<item>
<widget class="QLabel" name="statusIndicator">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Idle</string>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: gray; border-radius: 12px; }</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="endTime">
<property name="minimumSize">
<size>
<width>146</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>End time of last execution</string>
</property>
<property name="text">
<string>2015-01-01 00:00:00.000</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="errorExitLayout">
<item>
<widget class="QLabel" name="errorLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Error:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="errorText">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Process error status</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="exitLabel">
<property name="minimumSize">
<size>
<width>30</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Exit:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="exitCode">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Return code</string>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="exitText">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Process exit status</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPlainTextEdit" name="logEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<family>Monospace</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="toolTip">
<string>Output log (stdout + stderr)</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources>
<include location="../resources/res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SimplePTTCommandOutputDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>273</x>
<y>357</y>
</hint>
<hint type="destinationlabel">
<x>273</x>
<y>189</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SimplePTTCommandOutputDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>273</x>
<y>357</y>
</hint>
<hint type="destinationlabel">
<x>273</x>
<y>189</y>
</hint>
</hints>
</connection>
</connections>
</ui>

Wyświetl plik

@ -17,6 +17,7 @@
#include <QMessageBox>
#include <QFileDialog>
#include <QProcess>
#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);
}

Wyświetl plik

@ -19,6 +19,7 @@
#define INCLUDE_FEATURE_SIMPLEPTTGUI_H_
#include <QTimer>
#include <QDateTime>
#include "feature/featuregui.h"
#include "util/messagequeue.h"
@ -65,6 +66,14 @@ private:
std::vector<QString> m_statusColors;
std::vector<QString> 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);

Wyświetl plik

@ -362,6 +362,26 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="lastCommandLog">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Show last command status and log</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/listing.png</normaloff>:/listing.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>

Wyświetl plik

@ -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;

Wyświetl plik

@ -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);
}