Compare commits
53 Commits
631ade1954
...
1.3.2
Author | SHA1 | Date | |
---|---|---|---|
823e59a582 | |||
01cfbddfb1 | |||
838efd3945 | |||
9a65cb4456 | |||
df0951d671 | |||
60cc752819 | |||
57b4716e2a | |||
15f28e9ffd | |||
a07893ddab | |||
d0eb1d12d8 | |||
cd59a39569 | |||
67c8b2f472 | |||
5158878ce2 | |||
b6971c1db5 | |||
9df46a1c49 | |||
6765b12f0c | |||
3e925756cf | |||
b2798b349e | |||
64dce44fe1 | |||
7e96b65c1b | |||
276d65a9d8 | |||
ba71728979 | |||
e82742a609 | |||
6773a7243a | |||
22c8997f1e | |||
9531a08b4a | |||
c065b57f0c | |||
cef05b7511 | |||
bb35e985ad | |||
981a2ea13a | |||
b14b296011 | |||
1ef9853876 | |||
01d8312aa8 | |||
507586f9dc | |||
12ffa71455 | |||
a84f495d43 | |||
7e4b5006eb | |||
0a28f0d82c | |||
5427844977 | |||
a45e552d90 | |||
be28570d23 | |||
1509e8619c | |||
a8df026a80 | |||
a803907449 | |||
afd31f1b27 | |||
f8fef38009 | |||
cbe1fd387d | |||
1620b73d01 | |||
4ebdcf56a0 | |||
99b9419150 | |||
4307fb96a6 | |||
c35390b6d6 | |||
fff6bd2b49 |
@@ -15,7 +15,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
VERSION=1.1.1
|
||||
VERSION=1.3.2
|
||||
|
||||
INCLUDEPATH += plugins
|
||||
|
||||
@@ -78,6 +78,7 @@ contains( CONFIG, DesktopLinux ) {
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
progress_event.cpp \
|
||||
update_dc_event.cpp \
|
||||
mainwindow.cpp \
|
||||
utils.cpp \
|
||||
update.cpp \
|
||||
@@ -91,6 +92,7 @@ SOURCES += \
|
||||
HEADERS += \
|
||||
update.h \
|
||||
progress_event.h \
|
||||
update_dc_event.h \
|
||||
utils.h \
|
||||
mainwindow.h \
|
||||
git/git_client.h \
|
||||
|
@@ -120,13 +120,19 @@ QStringList GitClient::gitShowReason() {
|
||||
// %h: commit (short form)
|
||||
// %s: commit message
|
||||
// %cI: commit date, strict ISO 8601 format
|
||||
Command c("git show -s --format=\"c=%h m=%s d=%cI\"");
|
||||
// Note: use master branch. By convention, there is a ChangeLog file
|
||||
// in the root of the repository, which has to be always the last file
|
||||
// to be checked in when the customer repository somehow changed.
|
||||
Command c("git show origin/master -s --format=\"c=%h m=%s d=%cI\"");
|
||||
if (c.execute(m_customerRepository)) {
|
||||
QString const s = c.getCommandResult().trimmed();
|
||||
int const c = s.indexOf("c=");
|
||||
int const m = s.indexOf("m=");
|
||||
int const d = s.indexOf("d=");
|
||||
QString commit{""}, msg{""}, date{""};
|
||||
|
||||
QString msg = IsmasClient::getReasonForLastSendVersion();
|
||||
QString commit{""}, date{""};
|
||||
|
||||
if (c != -1) {
|
||||
int start = c + 2;
|
||||
if (m >= start) {
|
||||
@@ -136,7 +142,9 @@ QStringList GitClient::gitShowReason() {
|
||||
start = m + 2;
|
||||
if (d >= start) {
|
||||
length = d - start;
|
||||
msg += " (";
|
||||
msg = s.mid(start, length).trimmed();
|
||||
msg += ")";
|
||||
|
||||
start = d + 2;
|
||||
date = s.mid(start);
|
||||
@@ -330,7 +338,7 @@ QString GitClient::gitBlob(QString fileName) {
|
||||
if (fi.exists()) {
|
||||
QString const gitCommand = QString("git hash-object %1").arg(fileName);
|
||||
Command c(gitCommand);
|
||||
if (c.execute(m_workingDirectory)) {
|
||||
if (c.execute("/tmp")) {
|
||||
return c.getCommandResult().trimmed();
|
||||
}
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@ class GitClient : public QObject {
|
||||
|
||||
QString gitLastCommit(QString fileName);
|
||||
QStringList gitShowReason();
|
||||
QString gitBlob(QString fileName);
|
||||
static QString gitBlob(QString fileName);
|
||||
QString gitCommitForBlob(QString blob);
|
||||
bool gitIsFileTracked(QString file2name);
|
||||
};
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "ismas/ismas_client.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
@@ -393,6 +394,15 @@ QString IsmasClient::execOpkgCommand(QString const &info, QString const &version
|
||||
version.toStdString().c_str());
|
||||
}
|
||||
|
||||
QString IsmasClient::rsyncFile(QString const &info, QString const &version) {
|
||||
return updateNewsToIsmas("U0010",
|
||||
m_progressInPercent,
|
||||
RESULT_CODE::SUCCESS,
|
||||
"RSYNC FILE",
|
||||
info.toStdString().c_str(),
|
||||
version.toStdString().c_str());
|
||||
}
|
||||
|
||||
QString IsmasClient::updateTriggerSet(QString const &info, QString const &version) {
|
||||
return updateNewsToIsmas("U0010",
|
||||
m_progressInPercent,
|
||||
@@ -432,6 +442,13 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
|
||||
"\"ZONE\" : %d,"
|
||||
"\"INFO\" : \"%s\","
|
||||
"\"BLOB\" : \"%s\","
|
||||
"\"LAST-COMMIT\" : \"%s\","
|
||||
"\"SIZE\" : %d,"
|
||||
"\"LOADED\" : \"%s\""
|
||||
"},"
|
||||
"\"OPKG_COMMANDS\" : {"
|
||||
"\"BLOB\" : \"%s\","
|
||||
"\"LAST-COMMIT\" : \"%s\","
|
||||
"\"SIZE\" : %d,"
|
||||
"\"LOADED\" : \"%s\""
|
||||
"},"
|
||||
@@ -600,8 +617,9 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
|
||||
"}"
|
||||
"},"
|
||||
"\"SOFTWARE\": {"
|
||||
"\"RAUC\" : \"%s\","
|
||||
"\"OPKG\" : \"%s\","
|
||||
"\"APISM\" : {"
|
||||
"\"VERSION\" : \"%s\""
|
||||
"},"
|
||||
"\"ATBQT\" : {"
|
||||
"\"VERSION\" : \"%s\""
|
||||
"}"
|
||||
@@ -639,9 +657,15 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
|
||||
psa.tariff.zone,
|
||||
psa.tariff.info.toStdString().c_str(),
|
||||
psa.tariff.blob.toStdString().c_str(),
|
||||
psa.tariff.lastCommit.toStdString().c_str(),
|
||||
psa.tariff.size,
|
||||
psa.tariff.loadTime.toStdString().c_str(),
|
||||
|
||||
psa.opkg.blob.toStdString().c_str(),
|
||||
psa.opkg.lastCommit.toStdString().c_str(),
|
||||
psa.opkg.size,
|
||||
psa.opkg.loadTime.toStdString().c_str(),
|
||||
|
||||
psa.cash.blob.toStdString().c_str(),
|
||||
psa.cash.size,
|
||||
psa.conf.blob.toStdString().c_str(),
|
||||
@@ -723,8 +747,7 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
|
||||
psa.dc.gitBlob.toStdString().c_str(),
|
||||
psa.dc.gitLastCommit.toStdString().c_str(),
|
||||
|
||||
psa.sw.raucVersion.toStdString().c_str(),
|
||||
psa.sw.opkgVersion.toStdString().c_str(),
|
||||
psa.sw.apismVersion.toStdString().c_str(),
|
||||
psa.sw.atbQTVersion.toStdString().c_str(),
|
||||
|
||||
psa.pluginVersion.deviceController.toStdString().c_str(),
|
||||
@@ -807,7 +830,7 @@ QString IsmasClient::updateOfPSAActivated(QString const &version) { // sent ev
|
||||
}
|
||||
|
||||
QString IsmasClient::updateOfPSASucceeded(QString const &version) {
|
||||
m_progressInPercent = 0;
|
||||
m_progressInPercent = 100;
|
||||
return updateNewsToIsmas("U0001",
|
||||
m_progressInPercent,
|
||||
RESULT_CODE::SUCCESS,
|
||||
@@ -835,13 +858,13 @@ QString IsmasClient::jsonParseFailed(int resultCode, QString reason, QString con
|
||||
}
|
||||
|
||||
std::optional<QString> IsmasClient::finalResult(int resultCode, QString reason, QString const &version) {
|
||||
m_progressInPercent = 0;
|
||||
m_progressInPercent = 100;
|
||||
if (resultCode == RESULT_CODE::SUCCESS) {
|
||||
return updateNewsToIsmas("U0002",
|
||||
m_progressInPercent,
|
||||
RESULT_CODE::SUCCESS,
|
||||
resultCode,
|
||||
"FINAL-UPDATE-RESULT",
|
||||
"(re-)set WAIT state",
|
||||
reason.toStdString().c_str(),
|
||||
version.toStdString().c_str());
|
||||
}
|
||||
if (resultCode == RESULT_CODE::INSTALL_ERROR) {
|
||||
@@ -864,3 +887,18 @@ QString IsmasClient::updateOfPSAFailed(int resultCode, QString step,
|
||||
reason.toStdString().c_str(),
|
||||
version.toStdString().c_str());
|
||||
}
|
||||
|
||||
char const *IsmasClient::reason[REASON::ENTRIES] = {
|
||||
"TIME-TRIGGERED", "SERVICE", "DEV-TEST"
|
||||
};
|
||||
|
||||
QString IsmasClient::getReasonForLastSendVersion() {
|
||||
QString const &parentName = Utils::getParentName();
|
||||
if (parentName == "ATBQT") {
|
||||
return reason[REASON::SERVICE];
|
||||
}
|
||||
if (parentName == "systemd") {
|
||||
return reason[REASON::TIME_TRIGGERED];
|
||||
}
|
||||
return reason[REASON::DEV_TEST];
|
||||
}
|
||||
|
@@ -30,6 +30,13 @@ struct PSAInstalled {
|
||||
QString cpuSerial;
|
||||
} hw;
|
||||
|
||||
struct Opkg {
|
||||
int size;
|
||||
QString blob;
|
||||
QString lastCommit;
|
||||
QString loadTime;
|
||||
} opkg;
|
||||
|
||||
struct DC {
|
||||
QString versionHW;
|
||||
QString versionSW;
|
||||
@@ -39,8 +46,7 @@ struct PSAInstalled {
|
||||
} dc;
|
||||
|
||||
struct SoftWare {
|
||||
QString raucVersion;
|
||||
QString opkgVersion;
|
||||
QString apismVersion;
|
||||
QString atbQTVersion;
|
||||
} sw;
|
||||
|
||||
@@ -79,14 +85,18 @@ struct PSAInstalled {
|
||||
hw.linuxVersion = "N/A";
|
||||
hw.cpuSerial = "N/A";
|
||||
|
||||
opkg.size = -1;
|
||||
opkg.blob = "N/A";
|
||||
opkg.lastCommit = "N/A";
|
||||
opkg.loadTime = "N/A";
|
||||
|
||||
dc.versionHW = "N/A";
|
||||
dc.versionSW = "N/A";
|
||||
dc.gitBlob = "N/A";
|
||||
dc.gitLastCommit = "N/A";
|
||||
dc.size = -1;
|
||||
|
||||
sw.raucVersion = "N/A";
|
||||
sw.opkgVersion = "N/A";
|
||||
sw.apismVersion = "N/A";
|
||||
sw.atbQTVersion = "N/A";
|
||||
|
||||
pluginVersion.deviceController = "N/A";
|
||||
@@ -129,6 +139,7 @@ public:
|
||||
DIRECT_PORT = 7778
|
||||
};
|
||||
|
||||
|
||||
enum RESULT_CODE {
|
||||
SUCCESS=0,
|
||||
NO_UPDATE_NECESSARY=1,
|
||||
@@ -136,9 +147,20 @@ public:
|
||||
WRONG_PACKAGE=3,
|
||||
INSTALL_ERROR=4};
|
||||
|
||||
enum REASON {
|
||||
TIME_TRIGGERED = 0,
|
||||
SERVICE,
|
||||
DEV_TEST,
|
||||
ENTRIES
|
||||
};
|
||||
|
||||
static char const *reason[REASON::ENTRIES];
|
||||
|
||||
static std::optional<QString>
|
||||
sendRequestReceiveResponse(int port, QString const &request);
|
||||
|
||||
static QString getReasonForLastSendVersion();
|
||||
|
||||
int getProgressInPercent() const {return m_progressInPercent; }
|
||||
void setProgressInPercent(int procent) { m_progressInPercent = procent; }
|
||||
|
||||
@@ -159,6 +181,7 @@ public:
|
||||
QString errorUpdateTrigger(QString const &info, QString const &version = QString());
|
||||
QString gitFetch(QString const &info, QString const &version = QString());
|
||||
QString execOpkgCommand(QString const &info, QString const &version = QString());
|
||||
QString rsyncFile(QString const &info, QString const &version = QString());
|
||||
QString errorGitFetch(int resultCode, QString const &info, QString const &version = QString());
|
||||
QString updateOfPSAActivated(QString const &version = QString());
|
||||
// and update accepted
|
||||
|
152
main.cpp
152
main.cpp
@@ -32,6 +32,12 @@
|
||||
|
||||
#include <QThread>
|
||||
#include <QtWidgets>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef PTU5
|
||||
#define SERIAL_PORT "ttymxc2"
|
||||
@@ -39,93 +45,6 @@
|
||||
#define SERIAL_PORT "ttyUSB0"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static QGraphicsProxyWidget *createItem(const QSizeF &minimum = QSizeF(100.0, 100.0),
|
||||
const QSizeF &preferred = QSize(150.0, 100.0),
|
||||
const QSizeF &maximum = QSizeF(200.0, 100.0),
|
||||
const QString &name = "0")
|
||||
{
|
||||
QGraphicsProxyWidget *w = new QGraphicsProxyWidget;
|
||||
w->setWidget(new QPushButton(name));
|
||||
w->setData(0, name);
|
||||
w->setMinimumSize(minimum);
|
||||
w->setPreferredSize(preferred);
|
||||
w->setMaximumSize(maximum);
|
||||
|
||||
w->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
return w;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.setSceneRect(0, 0, 800, 480);
|
||||
|
||||
QSizeF minSize(30, 100);
|
||||
QSizeF prefSize(210, 100);
|
||||
QSizeF maxSize(300, 100);
|
||||
|
||||
QGraphicsProxyWidget *a = createItem(minSize, prefSize, maxSize, "A");
|
||||
QGraphicsProxyWidget *b = createItem(minSize, prefSize, maxSize, "B");
|
||||
QGraphicsProxyWidget *c = createItem(minSize, prefSize, maxSize, "C");
|
||||
QGraphicsProxyWidget *d = createItem(minSize, prefSize, maxSize, "D");
|
||||
QGraphicsProxyWidget *e = createItem(minSize, prefSize, maxSize, "E");
|
||||
QGraphicsProxyWidget *f = createItem(QSizeF(30, 50), QSizeF(150, 50), maxSize, "F (overflow)");
|
||||
QGraphicsProxyWidget *g = createItem(QSizeF(30, 50), QSizeF(30, 100), maxSize, "G (overflow)");
|
||||
|
||||
QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
|
||||
l->setSpacing(0);
|
||||
|
||||
QGraphicsWidget *w = new QGraphicsWidget(0, Qt::Window);
|
||||
w->setPos(20, 20);
|
||||
w->setLayout(l);
|
||||
|
||||
// vertical
|
||||
l->addAnchor(a, Qt::AnchorTop, l, Qt::AnchorTop);
|
||||
l->addAnchor(b, Qt::AnchorTop, l, Qt::AnchorTop);
|
||||
|
||||
l->addAnchor(c, Qt::AnchorTop, a, Qt::AnchorBottom);
|
||||
l->addAnchor(c, Qt::AnchorTop, b, Qt::AnchorBottom);
|
||||
l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop);
|
||||
l->addAnchor(c, Qt::AnchorBottom, e, Qt::AnchorTop);
|
||||
|
||||
l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom);
|
||||
l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom);
|
||||
|
||||
l->addAnchor(c, Qt::AnchorTop, f, Qt::AnchorTop);
|
||||
l->addAnchor(c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom);
|
||||
l->addAnchor(f, Qt::AnchorBottom, g, Qt::AnchorTop);
|
||||
l->addAnchor(c, Qt::AnchorBottom, g, Qt::AnchorBottom);
|
||||
|
||||
// horizontal
|
||||
l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
|
||||
l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft);
|
||||
l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
|
||||
|
||||
l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);
|
||||
l->addAnchor(c, Qt::AnchorRight, e, Qt::AnchorLeft);
|
||||
|
||||
l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight);
|
||||
l->addAnchor(e, Qt::AnchorRight, l, Qt::AnchorRight);
|
||||
l->addAnchor(d, Qt::AnchorRight, e, Qt::AnchorLeft);
|
||||
|
||||
l->addAnchor(l, Qt::AnchorLeft, f, Qt::AnchorLeft);
|
||||
l->addAnchor(l, Qt::AnchorLeft, g, Qt::AnchorLeft);
|
||||
l->addAnchor(f, Qt::AnchorRight, g, Qt::AnchorRight);
|
||||
|
||||
|
||||
scene.addItem(w);
|
||||
scene.setBackgroundBrush(Qt::darkGreen);
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
view.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
#endif
|
||||
|
||||
// argv[1]: file to send to dc
|
||||
int main(int argc, char *argv[]) {
|
||||
QByteArray const value = qgetenv("LC_ALL");
|
||||
@@ -140,27 +59,29 @@ int main(int argc, char *argv[]) {
|
||||
QApplication::setApplicationName("ATBUpdateTool");
|
||||
QApplication::setApplicationVersion(APP_VERSION);
|
||||
|
||||
#if 0
|
||||
// vorbereitend
|
||||
QGraphicsScene scene;
|
||||
scene.setSceneRect(0, 0, 800, 480);
|
||||
|
||||
QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
|
||||
l->setSpacing(0);
|
||||
|
||||
QGraphicsWidget *w = new QGraphicsWidget(0, Qt::Window);
|
||||
w->setPos(20, 20);
|
||||
w->setLayout(l);
|
||||
|
||||
QGraphicsView view(&scene);
|
||||
// view.show();
|
||||
#endif
|
||||
|
||||
if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling
|
||||
atbInstallMessageHandler(atbDebugOutput);
|
||||
setDebugLevel(LOG_NOTICE);
|
||||
}
|
||||
|
||||
//#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
|
||||
//#ifdef _POSIX_THREAD_PROCESS_SHARED
|
||||
// errno = 0;
|
||||
// int res = 0;
|
||||
// if ((res = sysconf(_SC_THREAD_PROCESS_SHARED)) < 0) {
|
||||
// if (errno != 0) {
|
||||
// qCritical() << "_POSIX_THREAD_PROCESS_SHARED NOT SUPPORTED"
|
||||
// << strerror(errno);
|
||||
// exit(-1);
|
||||
// }
|
||||
// } else {
|
||||
// if (res == _POSIX_THREAD_PROCESS_SHARED) {
|
||||
// Utils::printInfoMsg("_POSIX_THREAD_PROCESS_SHARED SUPPORTED");
|
||||
// }
|
||||
// }
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("Download tool for downloading device controller firmware, printer json-files and executing opkg-commands.");
|
||||
parser.addHelpOption();
|
||||
@@ -219,7 +140,8 @@ int main(int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
hwinf *hw = Update::loadDCPlugin(QDir(plugInDir), plugInName);
|
||||
// hw->dc_autoRequest(false);
|
||||
hw->dc_autoRequest(true);
|
||||
// hw->dc_openSerial(5, "115200", "ttymxc2", 1);
|
||||
|
||||
int machineNr = Utils::read1stLineOfFile("/etc/machine_nr");
|
||||
int customerNr = Utils::read1stLineOfFile("/etc/cust_nr");
|
||||
@@ -230,15 +152,31 @@ int main(int argc, char *argv[]) {
|
||||
QThread::currentThread()->setObjectName("main thread");
|
||||
qInfo() << "Main thread" << QThread::currentThreadId();
|
||||
|
||||
Worker worker(hw,
|
||||
customerNr,
|
||||
Worker worker(customerNr,
|
||||
machineNr,
|
||||
zoneNr,
|
||||
branchName,
|
||||
plugInName,
|
||||
workingDir,
|
||||
dryRun);
|
||||
|
||||
MainWindow mw(&worker);
|
||||
QString const customerNrStr(
|
||||
QString("customer_") + QString::number(customerNr).rightJustified(3, '0'));
|
||||
|
||||
QScopedPointer<Update> update(
|
||||
new Update(hw,
|
||||
&worker,
|
||||
QDir::cleanPath(workingDir + QDir::separator() + customerNrStr),
|
||||
customerNrStr,
|
||||
branchName,
|
||||
plugInName,
|
||||
workingDir,
|
||||
dryRun,
|
||||
nullptr,
|
||||
SERIAL_PORT,
|
||||
"115200"));
|
||||
|
||||
MainWindow mw(hw, &worker, update.get());
|
||||
worker.setMainWindow(&mw);
|
||||
|
||||
mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
|
||||
|
256
mainwindow.cpp
256
mainwindow.cpp
@@ -3,19 +3,119 @@
|
||||
#include "worker.h"
|
||||
#include "utils.h"
|
||||
#include "progress_event.h"
|
||||
#include "update_dc_event.h"
|
||||
#include "plugins/interfaces.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QScrollBar>
|
||||
|
||||
MainWindow::MainWindow(Worker *worker, QWidget *parent)
|
||||
|
||||
|
||||
#if EMERGENCY_LEAVE_BL==1
|
||||
static int step = 0;
|
||||
|
||||
void MainWindow::emergencyLeaveBL() {
|
||||
//
|
||||
qCritical() << __func__ << step;
|
||||
switch(step) {
|
||||
case 0:
|
||||
if (m_hw->dc_openSerial(5, "115200", "ttymxc2", 1)) {
|
||||
qCritical() << __func__ << "open ok";
|
||||
step++;
|
||||
QThread::msleep(2000);
|
||||
m_hw->dc_autoRequest(false);
|
||||
emit leaveBL();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
m_hw->bl_rebootDC();
|
||||
QThread::msleep(1000);
|
||||
qCritical() << __func__ << "reboot ok" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
step++;
|
||||
emit leaveBL();
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
m_hw->bl_startBL();
|
||||
QThread::msleep(1000);
|
||||
qCritical() << __func__ << "start" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
step++;
|
||||
emit leaveBL();
|
||||
break;
|
||||
case 7:
|
||||
case 9:
|
||||
case 11:
|
||||
case 13:
|
||||
case 15:
|
||||
m_hw->bl_checkBL();
|
||||
qCritical() << __func__ << "check" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
QThread::msleep(1500);
|
||||
++step;
|
||||
emit leaveBL();
|
||||
break;
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
qCritical() << __func__ << "is Up..." << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
if (m_hw->bl_isUp()) {
|
||||
qCritical() << __func__ << "is Up...OK" << step << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
QThread::msleep(5000);
|
||||
step = 16;
|
||||
} else {
|
||||
qCritical() << __func__ << "is Up...NO" << step << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
}
|
||||
++step;
|
||||
emit leaveBL();
|
||||
break;
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
qCritical() << __func__ << "stop" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
m_hw->bl_stopBL();
|
||||
QThread::msleep(1000);
|
||||
//m_hw->dc_closeSerial();
|
||||
++step;
|
||||
emit leaveBL();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
, m_hw(hw)
|
||||
, m_worker(worker)
|
||||
, m_width(70)
|
||||
, m_progressRunning(false)
|
||||
, m_progressValue(0) {
|
||||
, m_progressValue(0)
|
||||
, m_update(update)
|
||||
, m_updateStep(UpdateDcEvent::UpdateStep::NONE) {
|
||||
|
||||
#if EMERGENCY_LEAVE_BL==1
|
||||
QTimer *t = new QTimer(this);
|
||||
connect(t, SIGNAL(timeout()), this, SLOT(emergencyLeaveBL()));
|
||||
connect(this, SIGNAL(leaveBL()), this, SLOT(emergencyLeaveBL()), Qt::QueuedConnection);
|
||||
t->setSingleShot(true);
|
||||
t->start(1000);
|
||||
return;
|
||||
#endif
|
||||
|
||||
this->setStatusBar(new QStatusBar(this));
|
||||
QFont f;
|
||||
f.setStyleHint(QFont::Monospace);
|
||||
f.setWeight(QFont::Bold);
|
||||
f.setFamily("Misc Fixed");
|
||||
f.setPixelSize(12);
|
||||
this->statusBar()->setFont(f);
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->updateProgress->setRange(0, 100);
|
||||
@@ -28,8 +128,10 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
|
||||
lst << QString("Machine number : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3);
|
||||
lst << QString("Customer number : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3);
|
||||
lst << QString("Zone number : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3);
|
||||
lst << QString("APISM version : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3);
|
||||
lst << QString("").leftJustified(m_width-3, '=');
|
||||
|
||||
|
||||
ui->updateStatus->setText(lst.join('\n'));
|
||||
ui->updateStatus->setEnabled(true);
|
||||
|
||||
@@ -50,6 +152,7 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
|
||||
connect(m_worker, SIGNAL(restartExitTimer()),this,SLOT(onRestartExitTimer()));
|
||||
connect(m_worker, SIGNAL(appendText(QString,QString)),this,SLOT(onAppendText(QString,QString)));
|
||||
connect(m_worker, SIGNAL(showErrorMessage(QString,QString)),this, SLOT(onShowErrorMessage(QString,QString)));
|
||||
connect(m_worker, SIGNAL(showStatusMessage(QString,QString)),this, SLOT(onShowStatusMessage(QString,QString)));
|
||||
connect(m_worker, SIGNAL(replaceLast(QString,QString)),this,SLOT(onReplaceLast(QString,QString)));
|
||||
connect(m_worker, SIGNAL(replaceLast(QStringList,QString)),this, SLOT(onReplaceLast(QStringList,QString)));
|
||||
}
|
||||
@@ -108,6 +211,86 @@ void MainWindow::customEvent(QEvent *event) {
|
||||
} else {
|
||||
qCritical() << "!!! UNKNOWN SENDER !!!";
|
||||
}
|
||||
} else
|
||||
if (event->type() == UpdateDcEvent::type()) {
|
||||
UpdateDcEvent *pevent = (UpdateDcEvent *)event;
|
||||
UpdateDcEvent::UpdateStep const updateStep = pevent->updateStep();
|
||||
QObject const *sender = pevent->sender();
|
||||
if (sender == m_worker) {
|
||||
QDateTime const &recv = QDateTime::currentDateTime();
|
||||
QDateTime const &send = pevent->sendDateTime();
|
||||
qint64 const delay = recv.toMSecsSinceEpoch() - send.toMSecsSinceEpoch();
|
||||
switch(updateStep) {
|
||||
case UpdateDcEvent::UpdateStep::NONE:
|
||||
break;
|
||||
case UpdateDcEvent::UpdateStep::DC_REBOOT: {
|
||||
m_hw->bl_rebootDC();
|
||||
QString msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs)
|
||||
+ QString(": reset device controller (delay=%1ms").arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
m_updateStep = UpdateDcEvent::UpdateStep::DC_REBOOT;
|
||||
} break;
|
||||
case UpdateDcEvent::UpdateStep::BL_START: {
|
||||
QString const &msg = recv.toString(Qt::ISODateWithMs)
|
||||
+ QString(": start bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
m_hw->bl_startBL();
|
||||
if (pevent->count() == BL_START_COUNT) {
|
||||
m_updateStep = UpdateDcEvent::UpdateStep::BL_START;
|
||||
}
|
||||
} break;
|
||||
case UpdateDcEvent::UpdateStep::BL_CHECK: {
|
||||
if (m_updateStep != UpdateDcEvent::UpdateStep::BL_IS_UP) {
|
||||
QString const &msg = recv.toString(Qt::ISODateWithMs)
|
||||
+ QString(": request bootloader version (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
m_hw->bl_checkBL();
|
||||
//m_updateStep = UpdateDcEvent::UpdateStep::BL_CHECK;
|
||||
}
|
||||
} break;
|
||||
case UpdateDcEvent::UpdateStep::BL_IS_UP: {
|
||||
QString msg = recv.toString(Qt::ISODateWithMs)
|
||||
+ QString(": check running bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
if (m_updateStep != UpdateDcEvent::UpdateStep::BL_IS_UP) {
|
||||
if (m_hw->bl_isUp()) {
|
||||
msg = recv.toString(Qt::ISODateWithMs)
|
||||
+ QString(": bootloader running (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
m_updateStep = UpdateDcEvent::UpdateStep::BL_IS_UP;
|
||||
} else {
|
||||
msg = recv.toString(Qt::ISODateWithMs)
|
||||
+ QString(": bootloader stop requested (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
if (m_updateStep == UpdateDcEvent::UpdateStep::BL_STOP) {
|
||||
msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs)
|
||||
+ QString(": bootloader down (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
m_updateStep = UpdateDcEvent::UpdateStep::BL_IS_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case UpdateDcEvent::UpdateStep::BL_STOP: {
|
||||
QString const &msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs)
|
||||
+ QString(": stop bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
|
||||
emit m_worker->showStatusMessage("dc update", msg);
|
||||
Utils::printInfoMsg(msg.toUpper());
|
||||
//if (m_bootLoaderIsUp) {
|
||||
m_hw->bl_stopBL();
|
||||
m_updateStep = UpdateDcEvent::UpdateStep::BL_STOP;
|
||||
//}
|
||||
} break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QThread::yieldCurrentThread();
|
||||
@@ -137,6 +320,8 @@ void MainWindow::onQuit() {
|
||||
}
|
||||
|
||||
void MainWindow::scrollDownTextEdit() {
|
||||
qCritical() << "ON REPLACE LAST CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
|
||||
ui->updateStatus->setEnabled(true);
|
||||
|
||||
QTextCursor tmpCursor = ui->updateStatus->textCursor();
|
||||
@@ -146,6 +331,8 @@ void MainWindow::scrollDownTextEdit() {
|
||||
}
|
||||
|
||||
void MainWindow::onAppendText(QString text, QString suffix) {
|
||||
qCritical() << "ON APPEND CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
|
||||
QString editText = ui->updateStatus->toPlainText();
|
||||
if (!suffix.isNull() && suffix.size() > 0) {
|
||||
//qInfo() << "TEXT" << text << "SUFFIX" << suffix;
|
||||
@@ -153,21 +340,26 @@ void MainWindow::onAppendText(QString text, QString suffix) {
|
||||
editText += QString("\n").leftJustified(m_width-3, '=');
|
||||
editText += " ";
|
||||
}
|
||||
editText += (QString("\n") + text).leftJustified(m_width - (2 + suffix.size()) ) + suffix;
|
||||
QString const &add = (QString("\n") + text).leftJustified(m_width - (2 + suffix.size())) + suffix;
|
||||
editText += add;
|
||||
} else {
|
||||
editText += text.leftJustified(m_width-9);
|
||||
QString const &add = text.leftJustified(m_width-9);
|
||||
editText += add;
|
||||
}
|
||||
|
||||
Utils::printLineEditInfo(editText.split('\n'));
|
||||
ui->updateStatus->setPlainText(editText.trimmed());
|
||||
Utils::printLineEditInfo(editText.split('\n', QString::SplitBehavior::SkipEmptyParts));
|
||||
ui->updateStatus->setText(editText.trimmed());
|
||||
|
||||
scrollDownTextEdit();
|
||||
}
|
||||
|
||||
void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) {
|
||||
qCritical() << "ON REPLACE LAST CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
|
||||
int const s = newTextLines.size();
|
||||
if (s > 0) {
|
||||
QString editText = ui->updateStatus->toPlainText();
|
||||
QStringList lines = editText.split('\n');
|
||||
QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts);
|
||||
QString newText;
|
||||
if (lines.size() >= s) {
|
||||
for (int i = 0; i < s; ++i) {
|
||||
@@ -196,48 +388,40 @@ void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) {
|
||||
}
|
||||
|
||||
void MainWindow::onReplaceLast(QString text, QString suffix) {
|
||||
//qInfo() << "REPL TEXT" << text << "SUFFIX" << suffix;
|
||||
qCritical() << "ON REPLACE LAST CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
|
||||
QString editText = ui->updateStatus->toPlainText();
|
||||
QStringList lines = editText.split('\n');
|
||||
QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts);
|
||||
if (lines.size() > 0) {
|
||||
lines.removeLast();
|
||||
if (!suffix.isNull() && suffix.size() > 0 && suffix != "\n") {
|
||||
QString const add = text.leftJustified(m_width-10) + suffix;
|
||||
if (!add.isEmpty()) {
|
||||
lines += text.leftJustified(m_width-10) + suffix;
|
||||
}
|
||||
} else {
|
||||
QString const add = text.leftJustified(m_width-10);
|
||||
if (!add.isEmpty()) {
|
||||
lines += text.leftJustified(m_width-10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Utils::printLineEditInfo(lines);
|
||||
ui->updateStatus->setText(lines.join('\n').trimmed());
|
||||
scrollDownTextEdit();
|
||||
}
|
||||
|
||||
void MainWindow::onShowErrorMessage(QString title, QString text) {
|
||||
text = text.leftJustified(50, ' ');
|
||||
QMessageBox msgBox(QMessageBox::NoIcon, title,
|
||||
text, QMessageBox::Ok,
|
||||
this, Qt::FramelessWindowHint);
|
||||
msgBox.resize(100, 50);
|
||||
|
||||
// msg.setStyleSheet("background-color: rgb(0, 0, 0);")
|
||||
// msg.setStyleSheet("text-color: rgb(255, 255, 255);")
|
||||
|
||||
msgBox.setStyleSheet("QMessageBox{border: 1px solid black; background-color:white}");
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
msgBox.defaultButton()->setVisible(false);
|
||||
|
||||
QTimer *t = new QTimer(this);
|
||||
connect(t, SIGNAL(timeout()), msgBox.defaultButton(), SLOT(click()));
|
||||
t->setSingleShot(true);
|
||||
t->start(5 * 1000);
|
||||
|
||||
msgBox.show();
|
||||
msgBox.move(0, 0);
|
||||
|
||||
if(msgBox.exec() == QMessageBox::Ok) {
|
||||
// do something
|
||||
} else {
|
||||
// do something else
|
||||
}
|
||||
void MainWindow::onShowMessage(QString title, QString text) {
|
||||
this->statusBar()->clearMessage();
|
||||
this->statusBar()->showMessage( // timeout: 10000
|
||||
QString(title + " " + text).leftJustified(80, ' '), 10000);
|
||||
}
|
||||
|
||||
void MainWindow::onShowErrorMessage(QString title, QString text) {
|
||||
onShowMessage(title, text);
|
||||
}
|
||||
|
||||
void MainWindow::onShowStatusMessage(QString title, QString text) {
|
||||
onShowMessage(title, text);
|
||||
}
|
||||
|
34
mainwindow.h
34
mainwindow.h
@@ -3,13 +3,19 @@
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
#include <QStatusBar>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "worker.h"
|
||||
#include "update.h"
|
||||
#include "update_dc_event.h"
|
||||
|
||||
#define EMERGENCY_LEAVE_BL 0
|
||||
|
||||
class hwinf;
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -17,36 +23,60 @@ protected:
|
||||
void customEvent(QEvent *event) override;
|
||||
|
||||
public:
|
||||
MainWindow(Worker *worker, QWidget *parent = nullptr);
|
||||
MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
static const int START_PROGRESS_LOOP = -1;
|
||||
static const int STOP_PROGRESS_LOOP = -2;
|
||||
static const int BL_START_COUNT = 5;
|
||||
static const int BL_CHECK_COUNT = 5;
|
||||
static const int BL_IS_UP_COUNT = 5;
|
||||
static const int BL_STOP_COUNT = 5;
|
||||
|
||||
int progressValue() const { return m_progressValue; }
|
||||
hwinf *getPlugin() { return m_hw; }
|
||||
hwinf const *getPlugin() const { return m_hw; }
|
||||
Update *getUpdate() { return m_update; }
|
||||
Update const *getUpdate() const { return m_update; }
|
||||
UpdateDcEvent::UpdateStep updateStep() const { return m_updateStep; }
|
||||
void setUpdateStep(UpdateDcEvent::UpdateStep updateStep) { m_updateStep = updateStep; }
|
||||
|
||||
public slots:
|
||||
void onAppendText(QString, QString suffix = "");
|
||||
void onReplaceLast(QStringList, QString suffix = "");
|
||||
void onReplaceLast(QString, QString suffix = "");
|
||||
void onShowErrorMessage(QString, QString);
|
||||
void onShowStatusMessage(QString, QString);
|
||||
void onStopStartTimer();
|
||||
void onRestartExitTimer();
|
||||
void onEnableExit();
|
||||
void onDisableExit();
|
||||
#if EMERGENCY_LEAVE_BL==1
|
||||
void emergencyLeaveBL();
|
||||
#endif
|
||||
|
||||
signals:
|
||||
|
||||
#if EMERGENCY_LEAVE_BL==1
|
||||
void leaveBL();
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void onQuit();
|
||||
|
||||
private:
|
||||
void scrollDownTextEdit();
|
||||
void onShowMessage(QString, QString);
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
hwinf *m_hw;
|
||||
Worker *m_worker;
|
||||
int m_width;
|
||||
int const m_width;
|
||||
QTimer *m_startTimer;
|
||||
QTimer *m_exitTimer;
|
||||
bool m_progressRunning;
|
||||
int m_progressValue;
|
||||
Update *m_update;
|
||||
UpdateDcEvent::UpdateStep m_updateStep;
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
|
@@ -25,7 +25,7 @@
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>781</width>
|
||||
<height>461</height>
|
||||
<height>441</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
|
416
update.cpp
416
update.cpp
@@ -1,5 +1,8 @@
|
||||
#include "update.h"
|
||||
#include "worker.h"
|
||||
#include "utils.h"
|
||||
#include "update_dc_event.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QApplication>
|
||||
@@ -9,6 +12,7 @@
|
||||
#include <QTextStream>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegExp>
|
||||
#include <QApplication>
|
||||
|
||||
//#include <iostream>
|
||||
//#include <fstream>
|
||||
@@ -81,6 +85,7 @@ Update::Update(hwinf *hw,
|
||||
QString customerRepository,
|
||||
QString customerNrStr,
|
||||
QString branchName,
|
||||
QString pluginName,
|
||||
QString workingDir,
|
||||
bool dryRun,
|
||||
QObject *parent,
|
||||
@@ -94,8 +99,17 @@ Update::Update(hwinf *hw,
|
||||
, m_customerRepository(customerRepository)
|
||||
, m_customerNrStr(customerNrStr)
|
||||
, m_branchName(branchName)
|
||||
, m_pluginName(pluginName)
|
||||
, m_workingDir(workingDir)
|
||||
, m_dryRun(dryRun) {
|
||||
|
||||
qInfo() << "UPDATE: m_serialInterface ..." << m_serialInterface;
|
||||
qInfo() << "UPDATE: m_baudrate ..." << m_baudrate;
|
||||
qInfo() << "UPDATE: m_customerRepository ..." << m_customerRepository;
|
||||
qInfo() << "UPDATE: m_customerNr ..........." << m_customerNrStr;
|
||||
qInfo() << "UPDATE: m_branchName ..........." << m_branchName;
|
||||
qInfo() << "UPDATE: m_pluginName ..........." << m_pluginName;
|
||||
qInfo() << "UPDATE: m_workingDirectory ....." << m_workingDir;
|
||||
}
|
||||
|
||||
Update::~Update() {
|
||||
@@ -221,48 +235,99 @@ Update::DownloadResult Update::dc_downloadBinary(QByteArray const &b) const {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Update::startBootloader() const {
|
||||
qDebug() << "starting bootloader...";
|
||||
int nTry = 5;
|
||||
while (--nTry >= 0) {
|
||||
bool Update::startBootloader() const { // deprecated
|
||||
return false;
|
||||
#if 0
|
||||
int nStartTry = 5;
|
||||
while (--nStartTry >= 0) {
|
||||
m_hw->bl_startBL();
|
||||
QThread::msleep(5000);
|
||||
QThread::msleep(500);
|
||||
int nCheckTry = 10;
|
||||
while (--nCheckTry >= 0) {
|
||||
m_hw->bl_checkBL();
|
||||
QThread::msleep(500);
|
||||
if (m_hw->bl_isUp()) {
|
||||
qInfo() << "starting bootloader...OK";
|
||||
QThread::msleep(5000);
|
||||
return true;
|
||||
} else {
|
||||
qCritical() << "bootloader not up (" << nTry << ")";
|
||||
qCritical() << "bootloader not up ("
|
||||
<< nStartTry << "," << nCheckTry << ")" << QThread::currentThread();
|
||||
}
|
||||
}
|
||||
qCritical() << "starting bootloader...FAILED";
|
||||
}
|
||||
qCritical() << "starting bootloader...FAILED" << QThread::currentThread();
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Update::stopBootloader() const {
|
||||
qDebug() << "stopping bootloader...";
|
||||
int nTry = 5;
|
||||
while (--nTry >= 0) {
|
||||
m_hw->bl_stopBL();
|
||||
// stop bootloader: this MUST work -> otherwise the PSA has to be restarted
|
||||
// manually
|
||||
emit m_worker->showErrorMessage("dc update", "stopping bootloader...");
|
||||
|
||||
int nTryFinalize = 1; // could do this in an endless loop
|
||||
|
||||
do {
|
||||
// in principle, any value except BL_STOP will do, as we want to detect
|
||||
// change to BL_STOP
|
||||
m_worker->mainWindow()->setUpdateStep(UpdateDcEvent::UpdateStep::BL_CHECK);
|
||||
|
||||
QApplication::postEvent(
|
||||
m_worker->mainWindow(),
|
||||
new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_STOP, nTryFinalize));
|
||||
|
||||
QThread::sleep(1);
|
||||
|
||||
int const cntLimit = 20;
|
||||
int cnt = 0;
|
||||
while (++cnt < cntLimit &&
|
||||
m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_STOP) {
|
||||
// wait until bl_stopBL() has been sent
|
||||
QThread::msleep(500);
|
||||
if (!m_hw->bl_isUp()) {
|
||||
qInfo() << "stopping bootloader...OK";
|
||||
return true;
|
||||
}
|
||||
|
||||
QApplication::postEvent(
|
||||
m_worker->mainWindow(),
|
||||
new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_CHECK, nTryFinalize));
|
||||
QThread::sleep(1);
|
||||
|
||||
QApplication::postEvent(
|
||||
m_worker->mainWindow(),
|
||||
new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_IS_UP, nTryFinalize));
|
||||
QThread::sleep(1);
|
||||
|
||||
cnt = 0;
|
||||
while (++cnt < cntLimit &&
|
||||
m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_IS_DOWN) {
|
||||
// wait until done
|
||||
QThread::msleep(200);
|
||||
}
|
||||
qCritical() << "stopping bootloader...FAILED";
|
||||
return false;
|
||||
|
||||
} while (++nTryFinalize <= MainWindow::BL_STOP_COUNT &&
|
||||
m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_IS_DOWN);
|
||||
|
||||
return (m_worker->mainWindow()->updateStep() == UpdateDcEvent::UpdateStep::BL_IS_DOWN);
|
||||
}
|
||||
|
||||
// br is a index into a table, used for historical reasons.
|
||||
bool Update::openSerial(int br, QString baudrate, QString comPort) const {
|
||||
qDebug() << "opening serial" << br << baudrate << comPort << "...";
|
||||
if (m_hw->dc_openSerial(br, baudrate, comPort, 1)) { // 1 for connect
|
||||
qInfo() << "opening serial" << br << baudrate << comPort << "...OK";
|
||||
if (m_hw->dc_openSerial(br, baudrate, comPort, 1) == true) { // 1 for connect
|
||||
Utils::printInfoMsg(
|
||||
QString("OPENING SERIAL %1").arg(br)
|
||||
+ " " + baudrate + " " + comPort + "...OK");
|
||||
|
||||
// m_hw->dc_autoRequest(true);
|
||||
m_hw->dc_autoRequest(false);
|
||||
QThread::sleep(1);
|
||||
|
||||
Utils::printInfoMsg(QString("IS PORT OPEN %1").arg(m_hw->dc_isPortOpen()));
|
||||
return true;
|
||||
}
|
||||
qCritical() << "opening serial" << br << baudrate << comPort << "...FAILED";
|
||||
|
||||
Utils::printCriticalErrorMsg(
|
||||
QString("OPENING SERIAL %1").arg(br)
|
||||
+ " " + baudrate + " " + comPort + "...FAILED");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -275,13 +340,15 @@ bool Update::isSerialOpen() const {
|
||||
return m_hw->dc_isPortOpen();
|
||||
}
|
||||
|
||||
bool Update::resetDeviceController() const {
|
||||
bool Update::resetDeviceController() const { // deprecated
|
||||
return false;
|
||||
#if 0
|
||||
qDebug() << "resetting device controller...";
|
||||
m_hw->bl_rebootDC();
|
||||
// wait maximally 3 seconds, before starting bootloader
|
||||
QThread::sleep(1);
|
||||
qInfo() << "resetting device controller...OK";
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
QByteArray Update::loadBinaryDCFile(QString filename) const {
|
||||
@@ -319,17 +386,61 @@ bool Update::downloadBinaryToDC(QString const &bFile) const {
|
||||
}
|
||||
|
||||
/*
|
||||
Using the DC bootloader:
|
||||
1 : bl_reboot() // send to application, want DC2 to reset (in order to start
|
||||
// the bootloader)
|
||||
2 : bl_startBL(): // send within 4s after DC poewer-on, otherwise bl is left
|
||||
3 : bl_check(): // send command to verify if bl is up
|
||||
4 : bl_isUp(): // returns true if bl is up and running
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// USING THE DC BOOTLOADER
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
1 : bl_reboot() // send to application, want DC2 to reset (in order to
|
||||
// start the bootloader)
|
||||
//
|
||||
// NOTE: this function is NOT reliable !!! Sometimes it
|
||||
// simply does not work, in which case bl_startBL,
|
||||
// bl_checkBL and bl_isUp do not work as well.
|
||||
// Alas, there is no feedback if bl_reboot worked!
|
||||
//
|
||||
// NOTE: this function can be called only once per
|
||||
// minute, because once called again, the controller
|
||||
// performs some self-checks consuming some time.
|
||||
//
|
||||
// NOTE: after a successful bl_reboot(), the device is
|
||||
// waiting about 4 seconds in the bootloader. To stay in
|
||||
// the bootloader, we have to send the command
|
||||
// bl_startBL(), which is kind of a misnomer, as it
|
||||
// should be bl_doNotLeaveBL().
|
||||
//
|
||||
2 : bl_startBL(): // send within 4s after DC power-on, otherwise
|
||||
// bootloader is left.
|
||||
//
|
||||
// NOTE: a running bootloader is a MUST for the download
|
||||
// process of a device controller firmware as it does
|
||||
// the actual writing of the memory (the bl_reboot()
|
||||
// from above erases the available memory).
|
||||
//
|
||||
3 : bl_check(): // send command to verify if bl is up
|
||||
//
|
||||
// NOTE: this command is kind of a request that we want
|
||||
// to check if the bootloader is up. The device
|
||||
// (actually the bootloader) responds with its version.
|
||||
//
|
||||
4 : bl_isUp(): // returns true if bl is up and running
|
||||
//
|
||||
// NOTE: we know what the bootloader version actually is
|
||||
// as the bootloader does not change. By comparing the
|
||||
// string received in the previous step with this known
|
||||
// version string we know if the bootloader is up.
|
||||
//
|
||||
// NOTE FOR ALL PREVIOUS STEPS: execute them in their
|
||||
// own slots each to be sure to receive any possible
|
||||
// responds from the device.
|
||||
//
|
||||
5 : bl_sendAddress(blockNumber)
|
||||
// send start address, nr of 64-byte block, start with 0
|
||||
// will be sent only for following block-numbers:
|
||||
// 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
|
||||
// 0, 1024, 2048, 3072 and 4096, so basically every
|
||||
// 64kByte.
|
||||
// for other addresses nothing happens
|
||||
|
||||
6 : bl_wasSendingAddOK()
|
||||
@@ -349,54 +460,119 @@ bool Update::downloadBinaryToDC(QString const &bFile) const {
|
||||
// 10: OK
|
||||
|
||||
10 : bl_stopBL() // leave bl and start (the new) application
|
||||
//
|
||||
// NOTE: this function MUST work under all conditions.
|
||||
// Alas, there is no direct result for this command, so
|
||||
// the only way of knowing it was successful is to ask
|
||||
// the device if the bootloader is still running.
|
||||
// There is no problem to repeat this command until the
|
||||
// bootloader is really not running anymore.
|
||||
*/
|
||||
bool Update::updateBinary(char const *fileToSendToDC) {
|
||||
qInfo() << "UPDATING DEVICE CONTROLLER BINARY" << fileToSendToDC;
|
||||
qInfo() << "UPDATING DEVICE CONTROLLER FIRMWARE BINARY" << fileToSendToDC;
|
||||
QFile fn(fileToSendToDC);
|
||||
bool r;
|
||||
if ((r = fn.exists()) == true) {
|
||||
QFileInfo fi(fn);
|
||||
qInfo() << " UPDATING BINARY" << fi.fileName() << "(size=" << fi.size() << ")";
|
||||
if ((r = updateDC(fileToSendToDC)) == true) {
|
||||
qCritical() << QString(80, '*');
|
||||
qInfo() << " UPDATING BINARY" << fi.fileName() << "(size=" << fi.size() << ") DONE";
|
||||
qCritical() << QString(80, '*');
|
||||
Utils::printInfoMsg(
|
||||
QString(" UPDATING BINARY ") + fi.fileName()
|
||||
+ QString(" (size=%1").arg(fi.size()) + ") DONE");
|
||||
} else {
|
||||
qCritical() << QString(80, '*');
|
||||
qCritical() << " UPDATING BINARY" << fi.fileName() << "(size=" << fi.size() << ") FAILED";
|
||||
qCritical() << QString(80, '*');
|
||||
Utils::printCriticalErrorMsg(
|
||||
QString(" UPDATING BINARY ") + fi.fileName()
|
||||
+ QString(" (size=%1").arg(fi.size()) + ") FAILED");
|
||||
}
|
||||
} else {
|
||||
qCritical() << QString(80, '*');
|
||||
qCritical() << fileToSendToDC << "does not exist -> NO UPDATE OF DC FIRMWARE";
|
||||
qCritical() << QString(80, '*');
|
||||
Utils::printCriticalErrorMsg(
|
||||
QString(fileToSendToDC) + " DOES NOT EXIST -> NO UPDATE OF DC FIRMWARE");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Update::updateDC(QString bFile) const {
|
||||
qDebug() << "updating dc...";
|
||||
qDebug() << "updating dc: file to send" << bFile;
|
||||
if (!resetDeviceController()) {
|
||||
return false;
|
||||
qDebug() << "IN UPDATEDC: UPDATING DC: FILE TO SEND" << bFile;
|
||||
|
||||
m_worker->mainWindow()->setUpdateStep(UpdateDcEvent::UpdateStep::NONE);
|
||||
|
||||
QApplication::postEvent( // step 1: reset device controller
|
||||
m_worker->mainWindow(),
|
||||
new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::DC_REBOOT, 1));
|
||||
QThread::sleep(1);
|
||||
|
||||
for (int i=1; i <= MainWindow::BL_START_COUNT; ++i) {
|
||||
QApplication::postEvent( // step 2: start bootloader (5x)
|
||||
m_worker->mainWindow(),
|
||||
new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_START, i));
|
||||
QThread::sleep(1);
|
||||
}
|
||||
if (!startBootloader()) {
|
||||
// even when start seems to fail, stopping the boot loader does not harm
|
||||
stopBootloader();
|
||||
|
||||
int const cntLimit = 100; // wait until its for sure that bl_startBL()
|
||||
int cnt = 0; // has been excuted
|
||||
while (++cnt < cntLimit &&
|
||||
m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_START) {
|
||||
// wait until all bl_startBL() are done
|
||||
QThread::msleep(200);
|
||||
}
|
||||
|
||||
if (cnt == cntLimit) {
|
||||
// start events not received ???
|
||||
Utils::printCriticalErrorMsg("BL_START EVENT NOT RECEIVED AFTER 20 SECS");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_worker->mainWindow()->setUpdateStep(UpdateDcEvent::UpdateStep::BL_CHECK);
|
||||
|
||||
for (int i=1; i <= MainWindow::BL_IS_UP_COUNT; ++i) {
|
||||
QApplication::postEvent(m_worker->mainWindow(), new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_CHECK, i));
|
||||
QThread::sleep(1);
|
||||
QApplication::postEvent(m_worker->mainWindow(), new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_IS_UP, i));
|
||||
if (m_worker->mainWindow()->updateStep() == UpdateDcEvent::UpdateStep::BL_IS_UP) {
|
||||
break;
|
||||
}
|
||||
QThread::sleep(1);
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
while (++cnt < cntLimit &&
|
||||
m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_IS_UP) {
|
||||
// wait until all bl_startBL() are done
|
||||
QThread::msleep(200);
|
||||
}
|
||||
|
||||
if (cnt == cntLimit) {
|
||||
// really not up
|
||||
Utils::printCriticalErrorMsg("BL_IS_UP EVENT NOT RECEIVED AFTER 20 SECS");
|
||||
stopBootloader(); // try to stop bootloader whichhas been already started
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_worker->mainWindow()->updateStep() == UpdateDcEvent::UpdateStep::BL_IS_UP) {
|
||||
// bootloader MUST be running to download device-controller
|
||||
#if 0
|
||||
if (!downloadBinaryToDC(bFile)) {
|
||||
stopBootloader();
|
||||
qCritical() << "updating dc: " << bFile << "...FAILED";
|
||||
Utils::printCriticalErrorMsg(
|
||||
QString("UPDATING DC: ") + bFile + " ...DOWNLOAD FAILED");
|
||||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
Utils::printCriticalErrorMsg(
|
||||
QString("UPDATING DC: ") + bFile + " BOOT LOADER NOT RUNNING -> NO DOWNLOAD ("
|
||||
+ QThread::currentThread()->objectName() + ")");
|
||||
return false;
|
||||
}
|
||||
qInfo() << "updating dc: " << bFile << "...OK";
|
||||
|
||||
stopBootloader();
|
||||
//resetDeviceController();
|
||||
// do this unconditionally, even if bootloader is not running at all ->
|
||||
// the controller possibly tells us nonsense.
|
||||
if (!stopBootloader()) {
|
||||
Utils::printCriticalErrorMsg(
|
||||
QString("UPDATING DC: ") + bFile + " BOOT LOADER STILL RUNNING ("
|
||||
+ QThread::currentThread()->objectName() + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
QThread::sleep(3);
|
||||
Utils::printInfoMsg(QString("UPDATING DC: ") + bFile + " ...OK");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -518,25 +694,73 @@ void Update::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
|
||||
disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError()));
|
||||
}
|
||||
|
||||
QStringList Update::getDcSoftAndHardWareVersion() {
|
||||
m_hw->dc_autoRequest(true);
|
||||
QThread::sleep(1); // make sure the timer-slots are active
|
||||
|
||||
for (int i=0; i < 3; ++i) { // send explicit reuests to get
|
||||
// current SW/HW-versions
|
||||
m_hw->request_DC2_SWversion();
|
||||
m_hw->request_DC2_HWversion();
|
||||
QThread::sleep(1);
|
||||
}
|
||||
|
||||
QString const &hwVersion = m_hw->dc_getHWversion().toLower().trimmed();
|
||||
QString const &swVersion = m_hw->dc_getSWversion().toLower().trimmed();
|
||||
|
||||
m_hw->dc_autoRequest(false);
|
||||
QThread::sleep(1); // make sure the timer-slots are inactive
|
||||
|
||||
if (!hwVersion.isEmpty() && !swVersion.isEmpty()) {
|
||||
return QStringList() << hwVersion << swVersion;
|
||||
}
|
||||
|
||||
return QStringList() << "DC HW-version not available"
|
||||
<< "DC SW-version not available";
|
||||
}
|
||||
|
||||
bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
|
||||
//
|
||||
// ACHTUNG !!!
|
||||
//
|
||||
return true;
|
||||
|
||||
bool serialOpened = false;
|
||||
bool serialOpen = false;
|
||||
|
||||
if (!serialOpen) {
|
||||
if (!isSerialOpen()) { // open serial only if not already open
|
||||
if ((serialOpened = openSerial(baudrateMap.value(m_baudrate), m_baudrate, m_serialInterface)) == false) {
|
||||
qCritical() << "CANNOT OPEN" << m_serialInterface << "(BAUDRATE="
|
||||
<< m_baudrate << ")";
|
||||
QString const &parentName = Utils::getParentName();
|
||||
|
||||
if (parentName == "ATBQT" || parentName == "systemd") {
|
||||
// the tool was not called during 'service' ot during an automatic
|
||||
// update procedure. and it was called explicitly with libCAmaster.so
|
||||
if (m_pluginName.contains("master", Qt::CaseInsensitive)) {
|
||||
Utils::printCriticalErrorMsg(parentName
|
||||
+ " IS MASTER, BUT ATB-UPDATE-TOOL CALLED WITH libCAmaster.so");
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
if (Utils::isATBQTRunning()) { // manual testing
|
||||
if (m_pluginName.contains("master", Qt::CaseInsensitive)) {
|
||||
Utils::printCriticalErrorMsg(
|
||||
"ATBQT IS MASTER, BUT ATB-UPDATE-TOOL CALLED WITH libCAmaster.so");
|
||||
return false;
|
||||
}
|
||||
serialOpen = true;
|
||||
qInfo() << "SERIAL OPEN" << m_serialInterface << "(BAUDRATE=" << m_baudrate << ")";
|
||||
} else {
|
||||
if (m_pluginName.contains("slave", Qt::CaseInsensitive)) {
|
||||
Utils::printCriticalErrorMsg(
|
||||
"ATB-UPDATE-TOOL CALLED WITH libCAslave.so ALTHOUGH MASTER");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((serialOpened = openSerial(baudrateMap.value(m_baudrate),
|
||||
m_baudrate,
|
||||
m_serialInterface)) == false) {
|
||||
Utils::printCriticalErrorMsg(
|
||||
QString("CANNOT OPEN ")
|
||||
+ m_serialInterface
|
||||
+ "( BAUDRATE=" + m_baudrate + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hw->dc_autoRequest(false);
|
||||
|
||||
Utils::printInfoMsg(
|
||||
QString("SERIAL OPEN ") + m_serialInterface
|
||||
+ " (BAUDRATE=" + m_baudrate + ")");
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
@@ -546,41 +770,18 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
|
||||
QString fToWorkOn = (*it).trimmed();
|
||||
fToWorkOn = QDir::cleanPath(m_customerRepository + QDir::separator() + fToWorkOn);
|
||||
|
||||
static const QRegularExpression version("^.*dc2c[.][0-9][0-9][.][0-9][0-9][.]bin.*$");
|
||||
static const QRegularExpression version("^.*dc2c[.][0-9]{1,2}[.][0-9]{1,2}[.]bin.*$");
|
||||
if (fToWorkOn.contains(version)) {
|
||||
|
||||
qInfo() << QString(80, '*');
|
||||
qInfo() << "DO-UPDATE FILE-TO-WORK-ON" << fToWorkOn;
|
||||
qInfo() << QString(80, '*');
|
||||
|
||||
for (int i=0; i < 3; ++i) { // send explicit reuests to get
|
||||
// current SW/HW-versions
|
||||
m_hw->request_DC2_SWversion();
|
||||
m_hw->request_DC2_HWversion();
|
||||
QThread::sleep(1);
|
||||
}
|
||||
|
||||
QString const hwVersion = m_hw->dc_getHWversion().toLower();
|
||||
QString const fwVersion = m_hw->dc_getSWversion().toLower();
|
||||
|
||||
qInfo() << "current dc-hardware-version" << hwVersion;
|
||||
qInfo() << "current dc-firmware-version" << fwVersion;
|
||||
Utils::printInfoMsg("DO-UPDATE FILE-TO-WORK-ON " + fToWorkOn);
|
||||
|
||||
QFile fn(fToWorkOn);
|
||||
QFileInfo finfo(fn);
|
||||
if (!fn.exists()) { // check for broken link
|
||||
qCritical() << QString(80, '*');
|
||||
qCritical() << "FILE-TO-WORK-ON" << fn << "DOES NOT EXIST";
|
||||
qCritical() << QString(80, '*');
|
||||
Utils::printCriticalErrorMsg("DO-UPDATE FILE-TO-WORK-ON "
|
||||
+ fToWorkOn + " DOES NOT EXIST");
|
||||
res = false;
|
||||
} else {
|
||||
if (false) {
|
||||
//if (fwVersion.startsWith(linkTarget.completeBaseName())) {
|
||||
// qCritical() << "current dc-firmware-version" << fwVersion
|
||||
// << "already installed";
|
||||
// res = false;
|
||||
} else {
|
||||
res = true;
|
||||
bool updateBinaryRes = true;
|
||||
|
||||
qInfo() << "DOWNLOADING" << finfo.completeBaseName() << "TO DC";
|
||||
#if UPDATE_DC == 1
|
||||
@@ -589,7 +790,7 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
|
||||
// commands sent to dc-hardware
|
||||
qInfo() << "SET AUTO-REQUEST=FALSE";
|
||||
|
||||
if ((res = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
|
||||
if ((updateBinaryRes = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
|
||||
qCritical() << "downloaded binary" << fToWorkOn;
|
||||
++displayIndex;
|
||||
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
|
||||
@@ -599,15 +800,20 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
|
||||
|
||||
m_hw->dc_autoRequest(true); // turn auto-request setting on
|
||||
qInfo() << "SET AUTO-REQUEST=TRUE";
|
||||
qInfo() << "WAIT 10 SECS TO RECEIVE RESPONSES...";
|
||||
|
||||
QThread::sleep(10); // wait to be sure that responses
|
||||
// have been received
|
||||
qInfo() << "updated dc-hardware-version" << m_hw->dc_getHWversion();
|
||||
qInfo() << "updated dc-firmware-version" << m_hw->dc_getSWversion();
|
||||
#endif
|
||||
QStringList const &versions = Update::getDcSoftAndHardWareVersion();
|
||||
if (versions.size() >= 2) {
|
||||
if (updateBinaryRes == true) {
|
||||
qInfo() << "dc-hardware-version (UPDATED)" << versions[0];
|
||||
qInfo() << "dc-firmware-version (UPDATED)" << versions[1];
|
||||
} else {
|
||||
qInfo() << "dc-hardware-version (NOT UPDATED)" << versions[0];
|
||||
qInfo() << "dc-firmware-version (NOT UPDATED)" << versions[1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
res = updateBinaryRes;
|
||||
}
|
||||
} else if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
|
||||
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
@@ -675,8 +881,12 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
|
||||
}
|
||||
} // for (it = openLines.cbegin(); it != openLines.end(); ++it) {
|
||||
|
||||
m_hw->dc_autoRequest(true); // ALWAYS turn autoRequest ON
|
||||
qDebug() << "SET AUTO-REQUEST=TRUE";
|
||||
//m_hw->dc_autoRequest(true); // ALWAYS turn autoRequest ON
|
||||
//qDebug() << "SET AUTO-REQUEST=TRUE";
|
||||
|
||||
if (serialOpened) {
|
||||
m_hw->dc_closeSerial();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
3
update.h
3
update.h
@@ -27,6 +27,7 @@ class Update : public QObject {
|
||||
QString m_customerRepository;
|
||||
QString m_customerNrStr;
|
||||
QString m_branchName;
|
||||
QString m_pluginName;
|
||||
QString m_workingDir;
|
||||
bool m_maintenanceMode;
|
||||
bool m_dryRun;
|
||||
@@ -44,6 +45,7 @@ public:
|
||||
QString customerRepository,
|
||||
QString customerNrStr,
|
||||
QString branchName,
|
||||
QString pluginName,
|
||||
QString workingDir,
|
||||
bool dryRun = false,
|
||||
QObject *parent = nullptr,
|
||||
@@ -85,6 +87,7 @@ private:
|
||||
bool updateDeviceConf(QString jsFileToSendToDC);
|
||||
bool downloadJson(enum FileTypeJson type, int templateIdx,
|
||||
QString jsFileToSendToDC) const;
|
||||
QStringList getDcSoftAndHardWareVersion();
|
||||
|
||||
private slots:
|
||||
void readyReadStandardOutput();
|
||||
|
25
update_dc_event.cpp
Normal file
25
update_dc_event.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "update_dc_event.h"
|
||||
|
||||
QEvent::Type UpdateDcEvent::customEventType = QEvent::None;
|
||||
|
||||
UpdateDcEvent::UpdateDcEvent(QObject const *sender,
|
||||
UpdateStep updateStep,
|
||||
int count,
|
||||
QDateTime const &sendDateTime)
|
||||
: QEvent(UpdateDcEvent::type())
|
||||
, m_sender(sender)
|
||||
, m_updateStep(updateStep)
|
||||
, m_count(count)
|
||||
, m_sendDateTime(sendDateTime) {
|
||||
}
|
||||
|
||||
UpdateDcEvent::~UpdateDcEvent() {
|
||||
}
|
||||
|
||||
QEvent::Type UpdateDcEvent::type() {
|
||||
if (customEventType == QEvent::None) {
|
||||
int generatedType = QEvent::registerEventType();
|
||||
customEventType = static_cast<QEvent::Type>(generatedType);
|
||||
}
|
||||
return customEventType;
|
||||
}
|
40
update_dc_event.h
Normal file
40
update_dc_event.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef UPDATE_DC_EVENT_H_INCLUDED
|
||||
#define UPDATE_DC_EVENT_H_INCLUDED
|
||||
|
||||
#include <QEvent>
|
||||
#include <QDateTime>
|
||||
|
||||
class UpdateDcEvent : public QEvent {
|
||||
public:
|
||||
enum UpdateStep { NONE, DC_REBOOT, BL_START, BL_CHECK, BL_CHECK_AFTER_STOP, BL_IS_UP, BL_IS_DOWN, BL_STOP};
|
||||
|
||||
private:
|
||||
QObject const *m_sender;
|
||||
UpdateStep m_updateStep;
|
||||
int m_count;
|
||||
QDateTime m_sendDateTime;
|
||||
|
||||
public:
|
||||
explicit UpdateDcEvent(QObject const *sender, UpdateStep updateStep,
|
||||
int count,
|
||||
QDateTime const &sendDateTime = QDateTime::currentDateTime());
|
||||
virtual ~UpdateDcEvent();
|
||||
static QEvent::Type type();
|
||||
|
||||
QObject const *sender() { return m_sender; }
|
||||
QObject const *sender() const { return m_sender; }
|
||||
|
||||
void setUpdateStep(UpdateStep updateStep) { m_updateStep = updateStep; }
|
||||
UpdateStep updateStep() { return m_updateStep; }
|
||||
UpdateStep updateStep() const { return m_updateStep; }
|
||||
int count() const { return m_count; }
|
||||
void setCount(int count) { m_count = count; }
|
||||
QDateTime &sendDateTime() { return m_sendDateTime; }
|
||||
QDateTime const &sendDateTime() const { return m_sendDateTime; }
|
||||
|
||||
private:
|
||||
static QEvent::Type customEventType;
|
||||
};
|
||||
|
||||
|
||||
#endif // PROGRESS_EVENT_H_INCLUDED
|
138
utils.cpp
138
utils.cpp
@@ -1,9 +1,14 @@
|
||||
#include "utils.h"
|
||||
#include "message_handler.h"
|
||||
#include "git/git_client.h"
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
|
||||
int Utils::read1stLineOfFile(QString fileName) {
|
||||
QFile f(fileName);
|
||||
@@ -86,3 +91,136 @@ QString Utils::rstrip(QString const &str) {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Utils::sameFilesInDirs(QDir const &dir1, QDir const &dir2,
|
||||
QStringList const &nameFilters) {
|
||||
if (!dir1.exists()) {
|
||||
printCriticalErrorMsg(dir1.dirName() + " DOES NOT EXIST");
|
||||
return false;
|
||||
}
|
||||
if (!dir2.exists()) {
|
||||
printCriticalErrorMsg(dir2.dirName() + " DOES NOT EXIST");
|
||||
return false;
|
||||
}
|
||||
if (dir1.absolutePath() == dir2.absolutePath()) {
|
||||
printCriticalErrorMsg(dir1.dirName() + " AND "+ dir2.dirName() + " HAVE SAME PATH");
|
||||
return false;
|
||||
}
|
||||
|
||||
// files, sorted by name
|
||||
QFileInfoList const &lst1 = dir1.entryInfoList(nameFilters, QDir::Files, QDir::Name);
|
||||
QFileInfoList const &lst2 = dir2.entryInfoList(nameFilters, QDir::Files, QDir::Name);
|
||||
|
||||
QStringList fileNameLst1{};
|
||||
QStringList fileNameLst2{};
|
||||
QListIterator<QFileInfo> i1(lst1);
|
||||
while (i1.hasNext()) {
|
||||
fileNameLst1 << i1.next().fileName();
|
||||
}
|
||||
QListIterator<QFileInfo> i2(lst2);
|
||||
while (i2.hasNext()) {
|
||||
fileNameLst2 << i2.next().fileName();
|
||||
}
|
||||
|
||||
if (fileNameLst1.isEmpty()) {
|
||||
qCritical() << "DIR1" << dir1.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
|
||||
return false;
|
||||
}
|
||||
if (fileNameLst2.isEmpty()) {
|
||||
qCritical() << "DIR1" << dir2.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
|
||||
return false;
|
||||
}
|
||||
if (fileNameLst1 != fileNameLst2) {
|
||||
printCriticalErrorMsg(dir1.dirName() + " AND " + dir2.dirName()
|
||||
+ " DIFFER: [" + fileNameLst1.join(',') + "],["
|
||||
+ fileNameLst2.join(',') + "]");
|
||||
return false;
|
||||
} else {
|
||||
printInfoMsg(dir1.dirName() + " AND " + dir2.dirName()
|
||||
+ " ARE EQUAL: [" + fileNameLst1.join(',') + "]");
|
||||
}
|
||||
|
||||
QStringList gitBlobLst1{};
|
||||
QStringList gitBlobLst2{};
|
||||
QListIterator<QFileInfo> i3(lst1);
|
||||
while (i3.hasNext()) {
|
||||
gitBlobLst1 << GitClient::gitBlob(i3.next().fileName());
|
||||
}
|
||||
QListIterator<QFileInfo> i4(lst2);
|
||||
while (i4.hasNext()) {
|
||||
gitBlobLst2 << GitClient::gitBlob(i4.next().fileName());
|
||||
}
|
||||
|
||||
if (gitBlobLst1.isEmpty()) {
|
||||
qCritical() << "DIR1" << dir1.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
|
||||
return false;
|
||||
}
|
||||
if (gitBlobLst2.isEmpty()) {
|
||||
qCritical() << "DIR1" << dir2.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gitBlobLst1 != gitBlobLst2) {
|
||||
printCriticalErrorMsg(dir1.dirName() + " AND " + dir2.dirName()
|
||||
+ " DIFFER: [" + gitBlobLst1.join(',') + "],["
|
||||
+ gitBlobLst2.join(',') + "]");
|
||||
return false;
|
||||
} else {
|
||||
printInfoMsg(dir1.dirName() + " AND " + dir2.dirName()
|
||||
+ " CONTAIN SAME GIT-BLOBS FOR FILES: [" + fileNameLst1.join(',') + "]");
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString Utils::getParentName() { // get name of parent process
|
||||
QString ppid = QString("/proc/%1/status").arg(getppid());
|
||||
QFile f(ppid);
|
||||
if (f.exists()) {
|
||||
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&f);
|
||||
in.setCodec("UTF-8");
|
||||
while(!in.atEnd()) {
|
||||
// Name: ATBQT
|
||||
QStringList line = in.readLine().split(':');
|
||||
if (line.size() == 2) {
|
||||
if (line[0].trimmed() == "Name") {
|
||||
return line[1].trimmed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Utils::isATBQTRunning() {
|
||||
QDirIterator it("/proc",
|
||||
QStringList() << "status",
|
||||
QDir::Files,
|
||||
QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
QString const &nextStatusFile = it.next();
|
||||
QFile f(nextStatusFile);
|
||||
if (f.exists()) {
|
||||
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&f);
|
||||
in.setCodec("UTF-8");
|
||||
while(!in.atEnd()) {
|
||||
// Name: ATBQT
|
||||
QStringList line = in.readLine().split(':');
|
||||
if (line.size() == 2) {
|
||||
if (line[0].trimmed() == "Name") {
|
||||
if (line[1].trimmed() == "ATBQT") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
7
utils.h
7
utils.h
@@ -7,6 +7,7 @@
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
|
||||
namespace Utils {
|
||||
int read1stLineOfFile(QString fileName);
|
||||
@@ -16,6 +17,12 @@ namespace Utils {
|
||||
void printLineEditInfo(QStringList const &lines);
|
||||
QString getTariffLoadTime(QString fileName);
|
||||
QString rstrip(QString const &str);
|
||||
bool sameFilesInDirs(QDir const &dir1, QDir const &dir2,
|
||||
QStringList const &nameFilters = {"*.json"});
|
||||
|
||||
|
||||
QString getParentName();
|
||||
bool isATBQTRunning();
|
||||
}
|
||||
|
||||
#endif // UTILS_H_INCLUDED
|
||||
|
275
worker.cpp
275
worker.cpp
@@ -15,6 +15,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QJsonParseError>
|
||||
#include <Qt>
|
||||
|
||||
#include <thread>
|
||||
|
||||
@@ -30,34 +31,34 @@ QString const Worker::UPDATE_STEP_DONE(" [done]");
|
||||
QString const Worker::UPDATE_STEP_FAIL(" [FAIL]");
|
||||
QString const Worker::UPDATE_STEP_SUCCESS(" [SUCCESS]");
|
||||
|
||||
Worker::Worker(hwinf *hw,
|
||||
int customerNr,
|
||||
Worker::Worker(int customerNr,
|
||||
int machineNr,
|
||||
int zoneNr,
|
||||
QString branchName,
|
||||
QString pluginName,
|
||||
QString workingDirectory,
|
||||
bool dryRun,
|
||||
QObject *parent,
|
||||
char const *serialInterface,
|
||||
char const *baudrate)
|
||||
: m_hw(hw)
|
||||
, m_workerThread("workerThread")
|
||||
: m_workerThread("workerThread")
|
||||
, m_customerNr(customerNr)
|
||||
, m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0'))
|
||||
, m_machineNr(machineNr)
|
||||
, m_zoneNr(zoneNr)
|
||||
, m_pluginName(pluginName)
|
||||
, m_workingDirectory(workingDirectory)
|
||||
, m_branchName(branchName)
|
||||
, m_customerRepositoryPath(QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(m_customerNrStr))
|
||||
, m_customerRepository(QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr))
|
||||
, m_update(new Update(m_hw, this, m_customerRepository, m_customerNrStr, m_branchName,
|
||||
m_workingDirectory, dryRun, parent, serialInterface, baudrate))
|
||||
, m_dryRun(dryRun)
|
||||
, m_parent(parent)
|
||||
, m_serialInterface(serialInterface)
|
||||
, m_baudrate(baudrate)
|
||||
, m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this)
|
||||
, m_osVersion(getOsVersion())
|
||||
, m_atbqtVersion(getATBQTVersion())
|
||||
, m_cpuSerial(getCPUSerial())
|
||||
, m_raucVersion(getRaucVersion())
|
||||
, m_opkgVersion(getOpkgVersion())
|
||||
, m_pluginVersionATBDeciceController(getPluginVersion("/opt/app/ATBAPP/plugins/libATBDeviceControllerPlugin.so"))
|
||||
, m_pluginVersionIngenicoISelf(getPluginVersion("/opt/app/ATBAPP/plugins/libIngenicoISelf_CCPlugin.so"))
|
||||
, m_pluginVersionMobilisisCalc(getPluginVersion("/opt/app/ATBAPP/plugins/libMOBILISIS_CalculatePricePlugin.so"))
|
||||
@@ -71,10 +72,22 @@ Worker::Worker(hwinf *hw,
|
||||
, m_updateProcessRunning(true)
|
||||
, m_returnCode(0)
|
||||
, m_progressValue(0)
|
||||
//, m_withoutIsmasDirectPort(true) /* useful for testing */ {
|
||||
, m_withoutIsmasDirectPort(false) /* useful for testing */ {
|
||||
|
||||
this->setObjectName("worker-object");
|
||||
QDir::setCurrent(m_workingDirectory);
|
||||
|
||||
// restart apism to make sure it is running ?
|
||||
// Command c("systemctl restart apism");
|
||||
// if (c.execute("/tmp")) {
|
||||
// QThread::sleep(10); // give APISM some time to reconnect
|
||||
// }
|
||||
|
||||
if (std::optional<QString> v = getApismVersion()) {
|
||||
m_apismVersion = v.value();
|
||||
}
|
||||
|
||||
qInfo() << "CURRENT TIME ..............." << QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
qInfo() << "OS VERSION ................." << m_osVersion;
|
||||
qInfo() << "ATBQT VERSION .............." << m_atbqtVersion;
|
||||
@@ -86,7 +99,9 @@ Worker::Worker(hwinf *hw,
|
||||
qInfo() << "MACHINE_NR ................." << m_machineNr;
|
||||
qInfo() << "ZONE_NR ...................." << m_zoneNr;
|
||||
qInfo() << "BRANCH_NAME ................" << m_branchName;
|
||||
qInfo() << "PLUGIN_NAME ................" << m_pluginName;
|
||||
qInfo() << "WORKING_DIRECTORY .........." << m_workingDirectory;
|
||||
qInfo() << "APISM VERSION .............." << m_apismVersion;
|
||||
|
||||
this->moveToThread(&m_workerThread);
|
||||
m_workerThread.start();
|
||||
@@ -112,9 +127,6 @@ Worker::~Worker() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_update) {
|
||||
delete m_update;
|
||||
}
|
||||
}
|
||||
|
||||
void Worker::setProgress(int progress) {
|
||||
@@ -139,22 +151,14 @@ void Worker::update() {
|
||||
}
|
||||
|
||||
void Worker::privateUpdate() {
|
||||
if (!m_mainWindow) {
|
||||
Utils::printCriticalErrorMsg("m_mainWindow NOT SET");
|
||||
return;
|
||||
}
|
||||
|
||||
m_updateProcessRunning = true;
|
||||
|
||||
bool sentIsmasLastVersionNotification = false;
|
||||
|
||||
//emit appendText("\nRestart APISM ...");
|
||||
//startProgressLoop();
|
||||
//Command c("systemctl restart apism");
|
||||
//if (c.execute("/tmp")) {
|
||||
// QThread::sleep(10); // give APISM some time to reconnect
|
||||
// stopProgressLoop();
|
||||
// emit replaceLast("Restart APISM ...", UPDATE_STEP_DONE);
|
||||
//} else {
|
||||
// stopProgressLoop();
|
||||
// emit replaceLast("Restart APISM ...", UPDATE_STEP_FAIL);
|
||||
//}
|
||||
|
||||
emit disableExit();
|
||||
|
||||
m_returnCode = -1;
|
||||
@@ -207,12 +211,10 @@ void Worker::privateUpdate() {
|
||||
}
|
||||
} else {
|
||||
m_ismasClient.setProgressInPercent(10);
|
||||
if (backendConnected()) {
|
||||
m_ismasClient.setProgressInPercent(20);
|
||||
if (updateTriggerSet()) {
|
||||
m_ismasClient.setProgressInPercent(30);
|
||||
m_ismasClient.setProgressInPercent(20);
|
||||
if (customerEnvironment()) {
|
||||
m_ismasClient.setProgressInPercent(40);
|
||||
m_ismasClient.setProgressInPercent(30);
|
||||
if (filesToUpdate()) {
|
||||
// send message to ISMAS about files which have been
|
||||
// checked in into git repository
|
||||
@@ -222,16 +224,16 @@ void Worker::privateUpdate() {
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.updateOfPSAContinues("CHECK-FILES-TO-UPDATE",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_ismasClient.setProgressInPercent(50);
|
||||
m_ismasClient.setProgressInPercent(40);
|
||||
if (updateFiles(50)) {
|
||||
m_ismasClient.setProgressInPercent(60);
|
||||
m_ismasClient.setProgressInPercent(50);
|
||||
if (syncCustomerRepositoryAndFS()) {
|
||||
m_ismasClient.setProgressInPercent(70);
|
||||
m_ismasClient.setProgressInPercent(60);
|
||||
if (sendIsmasLastVersionNotification()) {
|
||||
m_ismasClient.setProgressInPercent(80);
|
||||
m_ismasClient.setProgressInPercent(70);
|
||||
sentIsmasLastVersionNotification = true;
|
||||
if (saveLogFile()) {
|
||||
m_ismasClient.setProgressInPercent(90);
|
||||
m_ismasClient.setProgressInPercent(80);
|
||||
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
@@ -314,16 +316,6 @@ void Worker::privateUpdate() {
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -5;
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::BACKEND_CHECK_FAILURE,
|
||||
QString("ISMAS backend not available"));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
"ISMAS-BACKEND-CHECK",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -4;
|
||||
}
|
||||
}
|
||||
|
||||
m_ismasClient.setProgressInPercent(100);
|
||||
@@ -336,7 +328,6 @@ void Worker::privateUpdate() {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_PROCESS_FAILURE,
|
||||
QString("Update process failed"));
|
||||
if (std::optional<QString> s = m_ismasClient.finalResult(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
"FINAL-UPDATE-RESULT",
|
||||
m_updateStatus.m_statusDescription)) {
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") + s.value());
|
||||
@@ -345,9 +336,8 @@ void Worker::privateUpdate() {
|
||||
emit appendText(QString("UPDATE "), UPDATE_STEP_SUCCESS);
|
||||
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_PROCESS_SUCCESS,
|
||||
QString("Update process succeeded"));
|
||||
QString("Update process succeeded. Reset WAIT."));
|
||||
if (std::optional<QString> s = m_ismasClient.finalResult(IsmasClient::RESULT_CODE::SUCCESS,
|
||||
"FINAL-UPDATE-RESULT",
|
||||
m_updateStatus.m_statusDescription)) {
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") + s.value());
|
||||
@@ -364,34 +354,20 @@ void Worker::privateUpdate() {
|
||||
emit restartExitTimer();
|
||||
}
|
||||
|
||||
bool Worker::backendConnected() {
|
||||
// deactivated: REQ_SELF does not really help. Observation was that even
|
||||
// id ISMAS is reported as 'true', a following check of the update-trigger
|
||||
// button has no access to ISMAS.
|
||||
return true;
|
||||
|
||||
emit appendText("\nConnecting backend ...");
|
||||
|
||||
if (false) { // so linker removes dead code
|
||||
for (int repeat = 0; repeat < 100; ++repeat) {
|
||||
qInfo() << "REPEAT" << repeat << "In backendConnected() -> #M=APISM#C=REQ_SELF#J={}";
|
||||
startProgressLoop();
|
||||
std::optional<QString> Worker::getApismVersion() {
|
||||
for (int repeat = 0; repeat < 10; ++repeat) {
|
||||
qInfo() << "REPEAT" << repeat << "In getApismVersion() -> #M=APISM#C=REQ_SELF#J={}";
|
||||
std::optional<QString> result
|
||||
= IsmasClient::sendRequestReceiveResponse(
|
||||
IsmasClient::APISM::DIRECT_PORT, "#M=APISM#C=REQ_SELF#J={}");
|
||||
if (result) {
|
||||
stopProgressLoop();
|
||||
int progress = (m_mainWindow->progressValue()/10) + 10;
|
||||
setProgress(progress);
|
||||
|
||||
QString msg = result.value();
|
||||
qInfo() << "In backendConnected() -> APISM response" << msg;
|
||||
qInfo() << "In getApismVersion() -> APISM response" << msg;
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qCritical() << "(1) INVALID JSON MSG: PARSING FAILED (msg=" << msg << "):"
|
||||
<< parseError.error << parseError.errorString();
|
||||
setProgress(100);
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::JSON_PARSE_FAILURE,
|
||||
QString("(2) INVALID JSON %1 %2 %3")
|
||||
.arg(msg)
|
||||
@@ -401,100 +377,39 @@ bool Worker::backendConnected() {
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.jsonParseFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
m_updateStatus.m_statusDescription));
|
||||
emit replaceLast("Connecting backend ...", UPDATE_STEP_FAIL);
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!document.isObject()) {
|
||||
qCritical() << "FILE IS NOT A JSON OBJECT!";
|
||||
setProgress(100);
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::JSON_PARSE_FAILURE,
|
||||
QString("NOT A JSON-OBJECT %1").arg(msg));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.jsonParseFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
m_updateStatus.m_statusDescription));
|
||||
emit replaceLast("Connecting backend ...", UPDATE_STEP_FAIL);
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
setProgress(progress + 1);
|
||||
|
||||
QJsonObject obj = document.object();
|
||||
QStringList keys = obj.keys().filter("CMD_GET_APISMSTATUS_RESPONSE");
|
||||
if (keys.size() == 1) {
|
||||
QString const key = keys.at(0);
|
||||
QJsonValue v = obj.value(key);
|
||||
if (v.isObject()) {
|
||||
obj = v.toObject();
|
||||
bool ismas = obj.value("ISMAS").toBool();
|
||||
QString status = obj.value("Broker").toString();
|
||||
qInfo() << "REPEAT" << repeat << "In backendConnected() Broker=<"
|
||||
<< status << ">, ISMAS=<" << (ismas ? "true>" : "false>");
|
||||
if (ismas) {
|
||||
if (status == "Connected") {
|
||||
// do not send, as this would result in a corrupted wait button
|
||||
// but update the user-interface
|
||||
setProgress(100);
|
||||
emit replaceLast("Connecting backend ...", UPDATE_STEP_OK);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::BACKEND_CHECK,
|
||||
QString ("REPEAT %1 Broker=<").arg(repeat)
|
||||
+ status + ">, ISMAS=<" + (ismas ? "true>" : "false>"));
|
||||
//IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
// QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
// m_ismasClient.updateOfPSAContinues("BACKEND-CHECK", m_updateStatus.m_statusDescription));
|
||||
|
||||
qInfo() << "BACKEND-CHECK" << m_updateStatus.m_statusDescription;
|
||||
emit showErrorMessage("Check backend connection", m_updateStatus.m_statusDescription);
|
||||
QThread::sleep(6);
|
||||
continue;
|
||||
} else {
|
||||
setProgress(100);
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::BACKEND_CHECK_FAILURE,
|
||||
"CMD_GET_APISM_STATUS_RESPONSE KEY NOT A JSON-OBJECT");
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
m_updateStatus.m_statusDescription));
|
||||
emit showErrorMessage("check backend connection", m_updateStatus.m_statusDescription);
|
||||
emit replaceLast("Connecting backend ...", UPDATE_STEP_FAIL);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
setProgress(100);
|
||||
if (keys.size() != 1) {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::BACKEND_CHECK_FAILURE,
|
||||
"CMD_GET_APISMSTATUS_RESPONSE KEY NOT AVAILABLE");
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
m_updateStatus.m_statusDescription));
|
||||
emit showErrorMessage("check backend connection", m_updateStatus.m_statusDescription);
|
||||
emit replaceLast("Connecting backend ...", UPDATE_STEP_FAIL);
|
||||
return false;
|
||||
}
|
||||
|
||||
emit showErrorMessage("apism response", m_updateStatus.m_statusDescription);
|
||||
return std::nullopt;
|
||||
} else {
|
||||
stopProgressLoop();
|
||||
int progress = (m_mainWindow->progressValue()/10) + 10;
|
||||
setProgress(progress);
|
||||
QString const key = keys.at(0);
|
||||
QJsonValue v = obj.value(key);
|
||||
return v.toObject().value("Version").toString();
|
||||
}
|
||||
} else {
|
||||
QThread::sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
setProgress(100);
|
||||
|
||||
emit replaceLast("Connecting backend", UPDATE_STEP_FAIL);
|
||||
emit showErrorMessage("Error", "Backend not available");
|
||||
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::BACKEND_NOT_CONNECTED,
|
||||
QString("NO BACKEND CONNECTION"));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.errorBackendNotConnected(m_updateStatus.m_statusDescription, ""));
|
||||
}
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#define CHECK_UPDATE_TRIGGER_SET "Check update trigger ..."
|
||||
@@ -509,13 +424,18 @@ bool Worker::updateTriggerSet() {
|
||||
int const startMs = QTime::currentTime().msecsSinceStartOfDay();
|
||||
|
||||
for (int repeat = 1; repeat <= 100; ++repeat) {
|
||||
|
||||
qInfo() << "UPDATE TRIGGER SET -> REPEAT" << repeat;
|
||||
|
||||
if (repeat > 1) {
|
||||
int const durationMs = QTime::currentTime().msecsSinceStartOfDay() - startMs;
|
||||
qInfo() << "REPEAT" << repeat
|
||||
<< QString("DURATION: %1.%2s").arg(durationMs / 1000).arg(durationMs % 1000);
|
||||
QString const &msg = QString("elapsed: %1.%2s").arg(durationMs / 1000).arg(durationMs % 1000);
|
||||
qInfo() << "REPEAT" << msg;
|
||||
emit showErrorMessage("check update trigger", msg);
|
||||
} else {
|
||||
emit showErrorMessage("check update trigger", "");
|
||||
}
|
||||
|
||||
if ((repeat % 10) == 0) {
|
||||
qInfo() << "CHECK UPDATE TRIGGER. RESTART APISM ...";
|
||||
Command c("systemctl restart apism");
|
||||
@@ -876,7 +796,6 @@ bool Worker::filesToUpdate() {
|
||||
bool Worker::updateFiles(quint8 percent) {
|
||||
QStringList filesToDownload;
|
||||
m_displayIndex = 0;
|
||||
|
||||
startProgressLoop();
|
||||
for (int i = 0; i < m_filesToUpdate.size(); ++i) {
|
||||
QString const fName = m_filesToUpdate.at(i);
|
||||
@@ -931,7 +850,7 @@ bool Worker::updateFiles(quint8 percent) {
|
||||
if (fName.contains("print", Qt::CaseInsensitive)) {
|
||||
filesToDownload << fName; // download printer-config-files
|
||||
} else {
|
||||
static const QRegularExpression version("^.*dc2c[.][0-9][0-9][.][0-9][0-9][.]bin.*$");
|
||||
static const QRegularExpression version("^.*dc2c[.][0-9]{1,2}[.][0-9]{1,2}[.]bin.*$");
|
||||
if (fName.contains(version)) {
|
||||
filesToDownload << fName; // download device controller
|
||||
}
|
||||
@@ -940,16 +859,19 @@ bool Worker::updateFiles(quint8 percent) {
|
||||
|
||||
stopProgressLoop();
|
||||
setProgress(100);
|
||||
bool ret = true;
|
||||
|
||||
if (filesToDownload.size() > 0) {
|
||||
Utils::printInfoMsg(QString("FILES_TO_DOWNLOAD_TO_PSA_HW ") + filesToDownload.join(','));
|
||||
ret = m_update->doUpdate(m_displayIndex, filesToDownload);
|
||||
|
||||
Update *update = m_mainWindow->getUpdate();
|
||||
if (update) {
|
||||
return update->doUpdate(m_displayIndex, filesToDownload);
|
||||
}
|
||||
} else {
|
||||
Utils::printCriticalErrorMsg("NO FILES_TO_DOWNLOAD_TO_PSA_HW");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Worker::syncCustomerRepositoryAndFS() {
|
||||
@@ -965,7 +887,7 @@ bool Worker::syncCustomerRepositoryAndFS() {
|
||||
}
|
||||
int progress = 10;
|
||||
setProgress(progress);
|
||||
QString const params("-vv "
|
||||
QString const params("-vvv "
|
||||
"--recursive "
|
||||
"--progress "
|
||||
"--checksum "
|
||||
@@ -988,8 +910,25 @@ bool Worker::syncCustomerRepositoryAndFS() {
|
||||
qInfo() << "EXECUTING CMD..." << cmd;
|
||||
if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) {
|
||||
QStringList result = c.getCommandResult().split('\n');
|
||||
QString const &p1 = "send_files mapped ";
|
||||
QString const &p2 = "of size";
|
||||
for (int i = 0; i < result.size(); ++i) {
|
||||
qInfo() << result.at(i);
|
||||
QString line = result.at(i);
|
||||
qInfo() << line;
|
||||
|
||||
// "send_files mapped etc/psa_tariff/tariff01.json of size 19339"
|
||||
int sendFilesAtPos = line.indexOf(p1);
|
||||
int ofSizeAtPos = line.indexOf(p2);
|
||||
if (sendFilesAtPos != -1 && ofSizeAtPos != -1) {
|
||||
sendFilesAtPos += p1.length();
|
||||
QString const &s = line.mid(sendFilesAtPos, ofSizeAtPos - sendFilesAtPos).trimmed();
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::RSYNC_FILE_SUCCESS,
|
||||
QString("RSYNC FILE ") + s.split("/").last() +
|
||||
" LAST-COMMIT: " + m_gc.gitLastCommit(s));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.rsyncFile(m_updateStatus.m_statusDescription, ""));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Utils::printCriticalErrorMsg(QString("CMD ") + cmd + " FAILED: "
|
||||
@@ -1001,9 +940,16 @@ bool Worker::syncCustomerRepositoryAndFS() {
|
||||
progress += 5;
|
||||
setProgress(progress);
|
||||
if (!error) {
|
||||
// now check tariff-files in etc and /etc/psa_tariff
|
||||
QDir dir1(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff"));
|
||||
QDir dir2("/etc/psa_tariff");
|
||||
if (Utils::sameFilesInDirs(dir1, dir2)) {
|
||||
setProgress(100);
|
||||
emit replaceLast(QString("Sync customer environment with filesystem ..."), UPDATE_STEP_DONE);
|
||||
return true;
|
||||
} else {
|
||||
// TODO: send message to ISMAS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1079,14 +1025,15 @@ QString Worker::getPluginVersion(QString const &pluginFileName) const {
|
||||
|
||||
QStringList Worker::getDCVersion() const {
|
||||
QStringList lst = (QStringList() << "N/A" << "N/A");
|
||||
if (m_hw) {
|
||||
m_hw->dc_autoRequest(true); // turn auto-request setting on
|
||||
hwinf *hwi = m_mainWindow->getPlugin();
|
||||
if (hwi) {
|
||||
hwi->dc_autoRequest(true); // turn auto-request setting on
|
||||
|
||||
QByteArray const cmp(8, char(0));
|
||||
QByteArray hw(""), sw("");
|
||||
for (int i=0; i<5; ++i) {
|
||||
hw = m_hw->dc_getHWversion().toUtf8();
|
||||
sw = m_hw->dc_getSWversion().toUtf8();
|
||||
hw = hwi->dc_getHWversion().toUtf8();
|
||||
sw = hwi->dc_getSWversion().toUtf8();
|
||||
if (!hw.startsWith(cmp)) {
|
||||
lst.clear();
|
||||
qInfo() << hw << sw;
|
||||
@@ -1135,6 +1082,10 @@ PSAInstalled Worker::getPSAInstalled() {
|
||||
QString printSysDir("/etc/psa_config");
|
||||
QString tariffSysDir("/etc/psa_tariff");
|
||||
QString tariffRepoDir("etc/psa_tariff");
|
||||
QString opkgSysDir("/etc/psa_update");
|
||||
QString opkgRepoDir("etc/psa_update");
|
||||
QString const &absPathNameOpkg = QDir::cleanPath(opkgSysDir + QDir::separator() + "opkg_commands");
|
||||
QString const &absPathNameRepositoryOpkg = QDir::cleanPath(opkgRepoDir + QDir::separator() + "opkg_commands");
|
||||
QString absPathName;
|
||||
QString absPathNameRepository;
|
||||
|
||||
@@ -1167,14 +1118,18 @@ PSAInstalled Worker::getPSAInstalled() {
|
||||
psaInstalled.hw.linuxVersion = m_osVersion;
|
||||
psaInstalled.hw.cpuSerial = m_cpuSerial;
|
||||
|
||||
psaInstalled.opkg.blob = m_gc.gitBlob(absPathNameOpkg);
|
||||
psaInstalled.opkg.size = getFileSize(absPathNameOpkg);
|
||||
psaInstalled.opkg.loadTime = Utils::getTariffLoadTime(absPathNameOpkg);
|
||||
psaInstalled.opkg.lastCommit = m_gc.gitLastCommit(absPathNameRepositoryOpkg);
|
||||
|
||||
psaInstalled.dc.versionHW = deviceControllerVersionHW;
|
||||
psaInstalled.dc.versionSW = deviceControllerVersionSW;
|
||||
psaInstalled.dc.gitBlob = "N/A";
|
||||
psaInstalled.dc.gitLastCommit = "N/A";
|
||||
psaInstalled.dc.size = -1;
|
||||
|
||||
psaInstalled.sw.raucVersion = m_raucVersion;
|
||||
psaInstalled.sw.opkgVersion = m_opkgVersion;
|
||||
psaInstalled.sw.apismVersion = m_apismVersion;
|
||||
psaInstalled.sw.atbQTVersion = m_atbqtVersion;
|
||||
|
||||
psaInstalled.pluginVersion.deviceController = m_pluginVersionATBDeciceController;
|
||||
@@ -1211,6 +1166,14 @@ PSAInstalled Worker::getPSAInstalled() {
|
||||
return psaInstalled;
|
||||
}
|
||||
|
||||
hwinf *Worker::getPlugin() {
|
||||
return m_mainWindow ? m_mainWindow->getPlugin() : nullptr;
|
||||
}
|
||||
|
||||
hwinf const *Worker::getPlugin() const {
|
||||
return m_mainWindow ? m_mainWindow->getPlugin() : nullptr;
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* operators
|
||||
*/
|
||||
@@ -1324,6 +1287,10 @@ QDebug operator<< (QDebug debug, UpdateStatus status) {
|
||||
debug << QString("UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED: ")
|
||||
<< status.m_statusDescription;
|
||||
break;
|
||||
case UPDATE_STATUS::RSYNC_FILE_SUCCESS:
|
||||
debug << QString("UPDATE_STATUS::RSYNC_FILE_SUCCESS: ")
|
||||
<< status.m_statusDescription;
|
||||
break;
|
||||
case UPDATE_STATUS::EXEC_OPKG_COMMANDS:
|
||||
debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ")
|
||||
<< status.m_statusDescription;
|
||||
@@ -1447,6 +1414,10 @@ QString& operator<< (QString& str, UpdateStatus status) {
|
||||
str = QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ");
|
||||
str += status.m_statusDescription;
|
||||
break;
|
||||
case UPDATE_STATUS::RSYNC_FILE_SUCCESS:
|
||||
str = QString("UPDATE_STATUS::RSYNC_FILE_SUCCESS: ");
|
||||
str += status.m_statusDescription;
|
||||
break;
|
||||
//default:;
|
||||
}
|
||||
return str;
|
||||
|
26
worker.h
26
worker.h
@@ -9,6 +9,8 @@
|
||||
#include <QJsonObject>
|
||||
#include <QHash>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "worker_thread.h"
|
||||
#include "update.h"
|
||||
#include "git/git_client.h"
|
||||
@@ -41,6 +43,7 @@ enum class UPDATE_STATUS : quint8 {
|
||||
EXEC_OPKG_COMMANDS,
|
||||
RSYNC_UPDATES_FAILURE,
|
||||
RSYNC_UPDATES_SUCCESS,
|
||||
RSYNC_FILE_SUCCESS,
|
||||
JSON_PARSE_FAILURE,
|
||||
UPDATE_PROCESS_SUCCESS,
|
||||
UPDATE_PROCESS_FAILURE,
|
||||
@@ -71,24 +74,25 @@ class hwinf;
|
||||
class Worker : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
hwinf *m_hw;
|
||||
WorkerThread m_workerThread;
|
||||
int const m_customerNr;
|
||||
QString const m_customerNrStr;
|
||||
int const m_machineNr;
|
||||
int const m_zoneNr;
|
||||
QString const m_pluginName;
|
||||
QString const m_workingDirectory;
|
||||
QString const m_branchName;
|
||||
QString const m_customerRepositoryPath;
|
||||
QString const m_customerRepository;
|
||||
Update *m_update;
|
||||
bool const m_dryRun;
|
||||
QObject *m_parent;
|
||||
QString const m_serialInterface;
|
||||
QString const m_baudrate;
|
||||
IsmasClient m_ismasClient;
|
||||
GitClient m_gc;
|
||||
QString const m_osVersion;
|
||||
QString const m_atbqtVersion;
|
||||
QString const m_cpuSerial;
|
||||
QString const m_raucVersion;
|
||||
QString const m_opkgVersion;
|
||||
QString const m_pluginVersionATBDeciceController;
|
||||
QString const m_pluginVersionIngenicoISelf;
|
||||
QString const m_pluginVersionMobilisisCalc;
|
||||
@@ -110,6 +114,7 @@ class Worker : public QObject {
|
||||
MainWindow *m_mainWindow;
|
||||
int m_progressValue;
|
||||
bool m_withoutIsmasDirectPort;
|
||||
QString m_apismVersion;
|
||||
|
||||
bool executeOpkgCommand(QString opkgCommand);
|
||||
QString getOsVersion() const;
|
||||
@@ -128,11 +133,11 @@ public:
|
||||
static const QString UPDATE_STEP_FAIL;
|
||||
static const QString UPDATE_STEP_SUCCESS;
|
||||
|
||||
explicit Worker(hwinf *hw,
|
||||
int customerNr, // 281
|
||||
explicit Worker(int customerNr, // 281
|
||||
int machineNr,
|
||||
int zoneNr,
|
||||
QString branchName,
|
||||
QString pluginName,
|
||||
QString workingDir = ".",
|
||||
bool dryRun = false,
|
||||
QObject *parent = nullptr,
|
||||
@@ -141,6 +146,8 @@ public:
|
||||
~Worker();
|
||||
|
||||
void setMainWindow(MainWindow *mainWindow) { m_mainWindow = mainWindow; }
|
||||
hwinf *getPlugin();
|
||||
hwinf const *getPlugin() const;
|
||||
void setProgress(int progress);
|
||||
void startProgressLoop();
|
||||
void stopProgressLoop();
|
||||
@@ -154,6 +161,10 @@ public:
|
||||
int machineNr() const { return m_machineNr; }
|
||||
int customerNr() const { return m_customerNr; }
|
||||
int zoneNr() const { return m_zoneNr; }
|
||||
QString apismVersion() const { return m_apismVersion; }
|
||||
|
||||
MainWindow *mainWindow() { return m_mainWindow; }
|
||||
MainWindow const *mainWindow() const { return m_mainWindow; }
|
||||
|
||||
//friend QDebug operator<<(QDebug debug, Worker const &w) {
|
||||
// Q_UNUSED(w);
|
||||
@@ -169,6 +180,7 @@ signals:
|
||||
void replaceLast(QString, QString);
|
||||
void replaceLast(QStringList, QString);
|
||||
void showErrorMessage(QString title, QString description);
|
||||
void showStatusMessage(QString title, QString description);
|
||||
void stopStartTimer();
|
||||
void restartExitTimer();
|
||||
void enableExit();
|
||||
@@ -178,7 +190,6 @@ public slots:
|
||||
void update();
|
||||
|
||||
private slots:
|
||||
bool backendConnected();
|
||||
bool updateTriggerSet();
|
||||
bool customerEnvironment();
|
||||
bool filesToUpdate();
|
||||
@@ -190,6 +201,7 @@ private slots:
|
||||
private:
|
||||
PSAInstalled getPSAInstalled();
|
||||
void privateUpdate();
|
||||
std::optional<QString> getApismVersion();
|
||||
};
|
||||
|
||||
#endif // WORKER_H_INCLUDED
|
||||
|
Reference in New Issue
Block a user