Files
qt5-legatus-legacy/Lts/Plugins/GuezNasat/Gui/ConfigNasat/gna_nasat_gui_plugin.cpp
T
2026-08-13 18:33:10 +02:00

220 lines
6.4 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Gui Plugin for AlarmManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2016-10-05
*/
#include "gna_nasat_gui_plugin.h"
#include "gna_dialog.h"
#include <Proxies/GuezNasat/gna_operator_rights.h>
#include <LtsSession/lts_session.h>
#include <GuezNasat/logger.h>
#include <LtsWidgets/lts_drag_icon.h>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <LtsWidgets/lts_global_wait_dialog.h>
#include <QProcess>
#include <QTimer>
namespace GuezNasat
{
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
}
bool GuiPlugin::availableInPartition(IDL::PartitionType partition) const
{
return partition == IDL::PartitionType::Global;
}
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, getLogger("NasatAircraft"))
, m_dtc(nullptr)
, m_ftc(nullptr)
{}
bool InterfaceImpl::fetchInterfaces()
{
if (!m_session->getDtc<GuezNasat::DataInterface>(m_dtc))
return false;
if (!m_session->getFtc<GuezNasat::DataInterface>(m_ftc))
return false;
return true;
}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
if (m_session->partitionType() != IDL::PartitionType::Global)
return {};
QVector<LtsWidgets::PluginData> ret;
{
// Action 'Nasat Aircrafts' anlegen
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("NASAT Aircrafts");
plData.identifier = QStringLiteral("showNasatAircraft");
plData.menuIcon = QIcon(QLatin1String("icon:force_organization.svg"));
plData.operatorRight = OperatorRights::GuezNasatConfigurationShow;
plData.exercisePart = LtsWidgets::ExercisePart::ePlanning;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowConfigGuezNasatDialog(parent);
};
ret.append(plData);
}
#ifdef Q_OS_UNIX
{
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("Start NASAT Aircrafts");
plData.identifier = QStringLiteral("startNasatAircraft");
plData.menuIcon = QIcon(QLatin1String("icon:nasat-start.svg"));
plData.operatorRight = OperatorRights::GuezNasatConfigurationShow;
plData.exercisePart = LtsWidgets::ExercisePart::ePlanning;
plData.directFunc = [this](const LtsWidgets::PluginData &)
{
controlAircrafts();
};
ret += plData;
}
{
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("Stop NASAT Aircrafts");
plData.identifier = QStringLiteral("stopNasatAircraft");
plData.menuIcon = QIcon(QLatin1String("icon:nasat-stop.svg"));
plData.operatorRight = OperatorRights::GuezNasatConfigurationShow;
plData.exercisePart = LtsWidgets::ExercisePart::ePlanning;
plData.directFunc = [this](const LtsWidgets::PluginData &)
{
controlAircrafts(false);
};
ret += plData;
}
#endif
return ret;
}
void InterfaceImpl::controlAircrafts(bool start)
{
auto ssh = [this](const QString &cmd, bool ignoreExitCode)
{
DEBUG_LOG(m_logger) << "controlAircrafts: ssh => " << cmd;
const QString hostname(QStringLiteral("nasat@CEF06IFR03"));
const QString password(QStringLiteral("nasatnasat"));
// const QString hostname(QStringLiteral("ctc@localhost"));
// const QString password(QStringLiteral("ctc11de"));
QProcess *p = new QProcess(this);
p->setProgram(QStringLiteral("sshpass"));
/* disable host key checking, because some machines might have never connecting to the host,
* resulting in a missing host key and therefore a denied connection otherwise accepting
* the key via first, manual ssh connection */
const QString args(QStringLiteral("-p %1 ssh -o StrictHostKeyChecking=no %2 %3").arg(password, hostname, cmd));
p->setArguments(args.split(QStringLiteral(" ")));
connect(p, &QProcess::errorOccurred,
this, [this](QProcess::ProcessError )
{
QProcess *p = qobject_cast<QProcess *>(sender());
if (p == nullptr)
return;
new LtsWidgets::LtsMessageDialogNew(m_session->baseLayout(), tr("Aircraft operation failed: %1.").arg(p->errorString()));
p->deleteLater();
});
connect(p, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, [this, cmd, ignoreExitCode](int exitCode)
{
QProcess *p = qobject_cast<QProcess *>(sender());
if (p == nullptr)
return;
WARNING_LOG(m_logger) << "exit code for '" << cmd << "': " << exitCode;
if (!ignoreExitCode && exitCode != 137 /* (128 + 9(SIGKILL)) */) // ignore exit code (137 => SIGKILL) from killing liste2msg1Sender
new LtsWidgets::LtsMessageDialogNew(m_session->baseLayout(), tr("Aircraft operation failed with error id: %1").arg(exitCode));
p->deleteLater();
});
connect(p, &QProcess::readyReadStandardError,
this, [this, p, cmd]()
{
WARNING_LOG(m_logger) << "nasat ssh process error for '"<<cmd<<"': " << p->readAllStandardError();
});
connect(p, &QProcess::readyReadStandardOutput,
this, [this, p, cmd]()
{
WARNING_LOG(m_logger) << "nasat ssh process output for '"<<cmd<<"': " << p->readAllStandardOutput();
});
p->start();
return p;
};
auto stop = [ssh]()
{
ssh(QStringLiteral("killall -s9 liste2msg1Sender"), true); // force it !
};
LtsWidgets::LtsGlobalWaitDialog::getInstance()->wait(tr("Executing Aircraft operation"));
ssh(QStringLiteral("pwd"), true);
stop();
// wait and hope script was stopped already (kinda hacky)
QTimer::singleShot(3500, this, [this, start, ssh]()
{
if (start)
{
QProcess *p = ssh(QStringLiteral("./start_radio_sim"), false);
connect(p, &QProcess::started, // is "started" even if it didn't work
this, []()
{
LtsWidgets::LtsGlobalWaitDialog::getInstance()->done();
});
}
else
{
LtsWidgets::LtsGlobalWaitDialog::getInstance()->done();
}
});
}
QString InterfaceImpl::menuGroup() const
{
return tr("Participants / Aircrafts");
}
void InterfaceImpl::clearInterfaces()
{
m_ftc = nullptr;
m_dtc = nullptr;
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowConfigGuezNasatDialog(QWidget *parent)
{
return LtsWidgets::initDialog(new GuezNasatDialog(menuGroup(), parent),
m_ftc, m_dtc);
}
} // namespace NasatAircraft