Compare commits

...

31 Commits

Author SHA1 Message Date
823e59a582 Set version to 1.3.2 2023-09-09 15:09:59 +02:00
01cfbddfb1 Add update_dc_event 2023-09-09 15:08:03 +02:00
838efd3945 Show status message in the status bar of the GUI. 2023-09-09 15:06:58 +02:00
9a65cb4456 Add some debug message when adding content to the text edit of the GUI. 2023-09-09 15:06:21 +02:00
df0951d671 Add the steps to prepare the bootloader for device-controller-firmware download
using cutom-events of type update-dc-event.
2023-09-09 15:04:41 +02:00
60cc752819 Add connect for showning a status message in status bar. 2023-09-09 15:03:52 +02:00
57b4716e2a Add emergency test function: if device stays in bootloader then use it to
make the device to leave the bootloader.
2023-09-09 15:02:45 +02:00
15f28e9ffd Add m_update-object and prepare for doing the bootloader setup for downloading
the device controller firmware.
2023-09-09 15:01:03 +02:00
a07893ddab doUpdate() and updateDC(): communicate with main window to enter bootloader
(i.e. to prepare device for download of device controller firmware), but do not
perform an actual download at the moment.
2023-09-09 14:59:05 +02:00
d0eb1d12d8 Add some debug output to updateBinary(). 2023-09-09 14:57:49 +02:00
cd59a39569 Add some more debug output to updateBinary(). 2023-09-09 14:57:04 +02:00
67c8b2f472 Extended comment: USING THE BOOTLOADER. 2023-09-09 14:55:48 +02:00
5158878ce2 Extend comment for: USING THE BOOTLOADER.
Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen,
2023-09-09 14:54:48 +02:00
b6971c1db5 resetDeviceController(): deprecated. 2023-09-09 14:54:12 +02:00
9df46a1c49 Add some debug output to openSerial(). 2023-09-09 14:53:36 +02:00
6765b12f0c startBootloader(): deprecated. 2023-09-09 14:52:40 +02:00
3e925756cf Add getDcSoftAndHardWareVersion() utility. 2023-09-09 14:43:46 +02:00
b2798b349e Fixed reg-exp for name of device controller firmare version. 2023-09-09 14:41:53 +02:00
64dce44fe1 Move update-object into main window.
Activate using ISMAS WAIT button.
2023-09-09 14:40:43 +02:00
7e96b65c1b Move m_update-object to main window.
Add signal for showing status messages at status bar of ATBUpdateTool gui.
2023-09-09 14:38:53 +02:00
276d65a9d8 Add utility isATBQTRunning(). 2023-09-09 14:33:13 +02:00
ba71728979 Move the dc-plugin (and the update-object) into the gui-thread instead of the
worker thread, so the worker-thread cannot block itself when inside a slot
and therefore not able to react to qt-signals.
2023-09-09 14:30:53 +02:00
e82742a609 Add helper class update_dc_event to dend customer messages from the worker-thread
to the gui-thread. The gui-thread will then perform bl_rebootDC, bl_startBL,
bl_checkBL(), bl_isUp() and bl_stopBL().
2023-09-09 14:27:50 +02:00
6773a7243a Save name of device-controller-plugin (either libCAmaster or libCAslave)
in the Update-object.
2023-09-06 09:12:25 +02:00
22c8997f1e Set autoRequest to false and pass a pointer to the device-controller-plugin
to the main window instead to the worker (thread).
2023-09-06 09:10:14 +02:00
9531a08b4a Add a pointer to the device-controller-plugin. The main window will always be
owned by the GUI thread, and the GUI thread is loading the plugin. Hence the
worker-thread does not block itself when inside a QT slot.
2023-09-06 09:07:45 +02:00
c065b57f0c Remove direct member m_hw, a pointer to the device-controller-plugin.
The worker shall not load the plugin, otherwise it would block itself inside
an QT slot.
2023-09-06 09:04:43 +02:00
cef05b7511 Set version to 1.3.1: extended reason in send-last-version 2023-09-04 11:48:15 +02:00
bb35e985ad Using IsmasClient::getReasonForLastSendVersion() 2023-09-04 11:46:37 +02:00
981a2ea13a Added method getReasonForSendLastVersion() 2023-09-04 11:45:30 +02:00
b14b296011 Added utility getParentName() (name of parent process) 2023-09-04 11:42:12 +02:00
15 changed files with 834 additions and 172 deletions

View File

@ -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.3.0
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 \

View File

@ -129,7 +129,10 @@ QStringList GitClient::gitShowReason() {
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) {
@ -139,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);

View File

@ -1,4 +1,5 @@
#include "ismas/ismas_client.h"
#include "utils.h"
#include <cstring>
#include <cstdio>
@ -886,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];
}

View File

@ -139,6 +139,7 @@ public:
DIRECT_PORT = 7778
};
enum RESULT_CODE {
SUCCESS=0,
NO_UPDATE_NECESSARY=1,
@ -146,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; }

View File

@ -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"
@ -58,6 +64,24 @@ int main(int argc, char *argv[]) {
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();
@ -116,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");
@ -127,16 +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);

View File

@ -3,20 +3,110 @@
#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;
@ -62,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)));
}
@ -120,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();
@ -149,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();
@ -158,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;
@ -165,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) {
@ -208,25 +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) {
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);
}

View File

@ -10,7 +10,12 @@ 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
@ -18,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

View File

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

View File

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

View File

@ -2,9 +2,13 @@
#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);
@ -169,3 +173,54 @@ bool Utils::sameFilesInDirs(QDir const &dir1, QDir const &dir2,
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;
}

View File

@ -19,6 +19,10 @@ namespace Utils {
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

View File

@ -31,28 +31,30 @@ 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())
@ -70,8 +72,10 @@ 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 ?
@ -95,6 +99,7 @@ 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;
@ -122,9 +127,6 @@ Worker::~Worker() {
}
}
}
if (m_update) {
delete m_update;
}
}
void Worker::setProgress(int progress) {
@ -149,10 +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 disableExit();
m_returnCode = -1;
@ -790,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);
@ -845,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
}
@ -854,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() {
@ -1017,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;
@ -1157,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
*/

View File

@ -74,17 +74,20 @@ 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;
@ -130,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,
@ -143,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();
@ -158,6 +163,9 @@ public:
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);
// return debug;
@ -172,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();