Compare commits

..

51 Commits

Author SHA1 Message Date
990d257b09 Make sure the dc-data are vaild: set again the auto-request flag inside the CA-plugin.w 2023-11-07 09:33:42 +01:00
dfbad69ab1 Add some comments. Set version to 1.3.15. Removed worker_thread.h/.cpp. 2023-11-07 09:24:32 +01:00
5f0c86ba19 Minor: removed obsolete test-code. 2023-11-07 09:23:43 +01:00
3588b25e65 Removed any references to CA-plugin from MainWindow. 2023-11-07 09:18:04 +01:00
1f8b88b2b6 Update-object now proper memeber of worker-thread.w 2023-11-07 09:14:49 +01:00
0050ea35d0 Update to new interfaces.h 2023-11-07 09:13:15 +01:00
7e4c138d1b Fixed getDCVersion() as part of turning worker-object into its own
thread.
2023-11-07 09:12:17 +01:00
685568d4f6 Call execOpkgCommands(0 and downloadTpPSAHardware() helpers. 2023-11-07 09:11:42 +01:00
14b4c035da Add computeFilesToUpdate() and downloadFilesToPSA() helper functions. 2023-11-07 09:10:45 +01:00
90de2f415e Add new members to worker-class. 2023-11-07 09:10:01 +01:00
3cc71cb69b Minor: remove obsolete code. 2023-11-07 09:09:26 +01:00
fef7533d00 Minor: replace APPLY_... with DOWNLOAD... enum-variables. 2023-11-07 09:08:33 +01:00
e93058cc6b Turn worker-object into a thread. Don't do a moveToThread() anymore. 2023-11-07 09:07:08 +01:00
e65387aa60 Turned worker-object into a thread 2023-11-07 09:04:05 +01:00
904fa0374b Minor: removed empty line 2023-11-07 09:00:25 +01:00
4bf1bbe81f Removed references to update and ca-plugin.w 2023-11-06 16:23:43 +01:00
3ccdcbae51 Removed generation of upodate-object. This will be donw inside
worker(-thread), and only when it is really needed, i.e. when there
are json-files to be updated (or a deveice-controller).
2023-11-06 16:20:27 +01:00
8c50e6cf59 Added command-line option no-psa-hardware-update (future use for
multipass).
2023-11-06 16:19:36 +01:00
7e69846169 Minor: removed obsolete code (commented out). 2023-11-06 16:15:31 +01:00
34c55c576c Use new masterlib. NOTE: furture versions have to use the slave lib. 2023-11-03 13:50:22 +01:00
7c2c4d4b80 Use new interface file. 2023-11-03 13:49:56 +01:00
f9f698fd15 Save for the weekend: set version to 1.3.15. 2023-11-03 13:49:28 +01:00
b4457d8815 Fix debugging output. 2023-11-03 13:46:23 +01:00
3621777827 Do not disable the exit button. 2023-11-03 13:45:54 +01:00
003bd0bf77 Check if repository is corrupted: do not check for etc/ or
opt/-directories, as they may be not existent inside of the repository.
2023-11-03 13:44:15 +01:00
721c5dd7a5 MAke sure removeDuplicates() is called for list containing file to be
updated.
2023-10-31 09:16:24 +01:00
a24eb9fd8c Minor: removed unused, obsolete code (commented out). 2023-10-31 09:14:02 +01:00
24351b8342 Minor: add runtime information in debug output. 2023-10-31 09:12:43 +01:00
4b3a39b0e6 Set version to 1.3.14.
Add compile flag -C (so it is possible to use /*fall through*/ without
having the proprocessor to remove this comment.
2023-10-30 15:35:38 +01:00
a44b780d93 Minor: Add header for using RAII in sending SEND-LAST-VERSION to ISAMS. 2023-10-30 15:29:23 +01:00
19dfae9b56 Use output functions ISMAS(), GUI() and CONSOLE(), which point to friend
operators<< in Worker-class.
2023-10-30 15:28:25 +01:00
bef0d4fe12 Refactor the update process: streamline code. When WAIT button is not
active, the a clone or a fix of a defunct repository is possible, but
not more.
If WAIT button is active, the at least the opkg_commnds are executed. If
there are chenged files, they are handkled as wll.
2023-10-30 15:25:49 +01:00
72a2fc781c Minor: reove obsolete m_returnCode. 2023-10-30 15:24:33 +01:00
fc264689b1 Use and implement getAPISMYoctoVersion() and
getAPISMYoctoInstallationSTatus().
2023-10-30 15:22:59 +01:00
fc587456d5 Filling the QMap Worker:smap with data. 2023-10-30 15:21:26 +01:00
a2b933ab71 Minor: Added UPDATE_STEP_WRONG. 2023-10-30 15:20:15 +01:00
7d0fdf4d6d Small fixes:
1: fixed wrong parameters of a connect().
2: Minor: improved onQuit().
2023-10-30 15:17:59 +01:00
c2ce44c79b Adding three friend operator<< functions to output status information of
the update process: the first on outputs to CONSOLE(), the second one
outputs to ISMAS() and the last one to GUI(), i.e. the text edit of the
main window.
2023-10-30 15:15:30 +01:00
16a9556863 bool customerEnvironment();
bool filesToUpdate();
bool updateFiles();
bool syncCustomerRepositoryAndFS();
bool saveLogFile(): remove progress parameter.
2023-10-30 15:14:19 +01:00
48896f97ec Adding UPDATE_STEP_WRONG: helper variable to be used in text edit of
main window.
2023-10-30 15:13:04 +01:00
4486317cb2 dd declaration for getAPISMYoctoVersion() and
getAPISMYoctoInstallationStatus(): the first one returning the
yocto-version
of APIS, the second returning the installation status of APIS as display
in 'opkg info'.
2023-10-30 15:11:06 +01:00
6b9b88ea19 Adding member variables to check if customer repository was a fresh
clone, or if it was already existent.
2023-10-30 15:09:33 +01:00
99a99d95a1 Adding UPDATE_STEP enum plus associated interger defines.
Adding QMap: Worker::smap, which contains names of UPDATE_STEP-members.
2023-10-30 15:07:28 +01:00
d4ddbbee21 Add class UpdateProcessRunning: use for sending SEND-LAST-VERSION as
part of its destruktor: RAII-pattern.
2023-10-30 15:05:30 +01:00
34e5189945 comment out some debug output -> too much output. 2023-10-30 15:03:35 +01:00
c44c805238 Use some special output methods using ISMAS(), GUI() nad CONSOLE(). 2023-10-30 15:00:57 +01:00
196f1a730e gitPull(): don't use regex anumore, but just plain
string-matching/searching.
Regex seems to be quite error-prone.
2023-10-30 14:59:58 +01:00
7dc04c4422 Add helper function worker(), returning the worker-object. 2023-10-30 14:56:19 +01:00
5efac2619b sicherung der aenderungen 2023-10-23 16:16:11 +02:00
9b0f741b9b to be continued on monday 2023-10-22 19:44:45 +02:00
81c5f8ee7e Save for the weekend. 2023-10-20 13:55:18 +02:00
17 changed files with 2074 additions and 1380 deletions

View File

@@ -41,6 +41,44 @@ DEFINES += QT_DEPRECATED_WARNINGS
# up cloning of customer repository.
# 1.3.13: Fix: if the customer repository is corrupted, remove it and re-clone
# the repository (without checking the ISMAS-trigger (WAIT-)button.
# 1.3.14: Add additional check for sanity of customer repository using
# "git fsck".
# Stream-lined code of update process: massive refactoring.
# Added functionality: If WAIT button is not active, then an existing
# customer repository will be repaired, or a not existing repository
# will be cloned. The process stops then.
# However, if the WAIT button is active, the at least the commands in
# opkg_commands will be executed. Changed files in the customer
# repository will be worked on: tariff-files will be synced with the
# local filesystem, json-files will be downloaded to firmware.
# The device-controller firmware will be handled in a later version.
VERSION="1.3.15"
# Bug fixes found during testing.
# Don't disable Exit-button during update-process.
# Removed worker-thread with an own event-loop: only the GUI thread
# has an event loop. Tested JSON-downloads several times successfully
# (using the slave lib where the CA helper tool was active as master).
# Turned previous worker-object into its own thread, but without any
# own event-loop (so it cannot block anything inside the CA-plugin).
# PLANNED TODOS:
# 1: Das Repository wird repariert bwz. neu geklont. Unabhaengig vom WAIT.
# 2: Wenn der WAIT-Button aktiv ist, dann wird ein Repository repariert (neu
# geklont), aber zusaetzlich werden alle verfuegbaren Dateien als neu
# angesehen und die entsprechenden Aktionen durchgefuehrt: tariff-files
# spiegeln, json-files laden und dc laden. Also VORSICHT: das repository
# muss in diesem fall wirklich in ordnung sein.
# 3: Wurde keine Datei geaendert, kein initiales Clone und der WAIT-button
# nicht aktiv, so (passiert natuerlich nichts) kann man davon ausgehen,
# dass es sich um ein automatisches Update handelt. Dann koennte man im
# ISMAS eine entsprechende Meldung anzeigen als Teil von SEND-LAST-VERSION.
# Wenn der WAIT-button aktiv ist, dann werden zumindest die opkg-commands
# ausgefuehrt.
# 4: rsync: immer alle Dateien soiegeln (bis auf opkg-commands)
# 5: Falls das Tool mal abstuerzt, dann einen Signal-Handler (fuer TERM)
# installieren, sodass zumnidest SEND-LAST-VERSION mit rausgeht.
# 6: rsync: explizites Binary, nicht das in busybox enthaltene.
# 7: Ein ini-File oder sowas.
win32 {
BUILD_DATE=$$system("date /t")
@@ -52,7 +90,6 @@ win32 {
GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1")
VERSION="1.3.11"
EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}"
INCLUDEPATH += plugins
@@ -65,6 +102,8 @@ DEFINES+=APP_BUILD_DATE=\\\"$$BUILD_DATE\\\"
DEFINES+=APP_BUILD_TIME=\\\"$$BUILD_TIME\\\"
DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\"
# keep comments, as /* fall through */
QMAKE_CXXFLAGS += -C
QMAKE_CXXFLAGS += -g
QMAKE_CXXFLAGS += -Wno-deprecated-copy
@@ -73,14 +112,14 @@ contains( CONFIG, PTU5 ) {
CONFIG += link_pkgconfig
lessThan(QT_MAJOR_VERSION, 5): PKGCONFIG += qextserialport
QMAKE_CXXFLAGS += -O2 -std=c++17 # for GCC >= 4.7
QMAKE_CXXFLAGS += -Wno-deprecated-copy
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
ARCH = PTU5
DEFINES+=PTU5
}
contains( CONFIG, PTU5_YOCTO ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
QMAKE_CXXFLAGS += -std=c++17 # for GCC >= 4.7
QMAKE_CXXFLAGS += -Wno-deprecated-copy
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
PTU5BASEPATH = /opt/devel/ptu5
ARCH = PTU5
DEFINES+=PTU5
@@ -94,7 +133,7 @@ contains( CONFIG, DesktopLinux ) {
# QMAKE_CC = ccache $$QMAKE_CC
# QMAKE_CXX = ccache $$QMAKE_CXX
QMAKE_CXXFLAGS += -std=c++17
QMAKE_CXXFLAGS += -Wno-deprecated-copy
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
ARCH = DesktopLinux
DEFINES+=DesktopLinux
@@ -111,8 +150,7 @@ SOURCES += \
ismas/ismas_client.cpp \
process/command.cpp \
message_handler.cpp \
worker.cpp \
worker_thread.cpp
worker.cpp
HEADERS += \
update.h \
@@ -126,7 +164,6 @@ HEADERS += \
process/command.h \
message_handler.h \
worker.h \
worker_thread.h \
plugins/interfaces.h
FORMS += \

View File

@@ -279,6 +279,17 @@ std::optional<QStringList> GitClient::gitDiff(QString const &commits) {
return std::nullopt;
}
bool GitClient::gitFsck() {
bool r = false;
if (QDir(m_customerRepository).exists()) {
Command c("git fsck");
if ((r = c.execute(m_customerRepository)) == false) {
QString const &s = c.getCommandResult().trimmed();
Utils::printCriticalErrorMsg(QString("GIT FSCK FAILED: %1").arg(s));
}
}
return r;
}
/*
Hat sich nichts geaendert, so werden auch keine Commits <>..<> angezeigt
*/
@@ -291,55 +302,61 @@ std::optional<QString> GitClient::gitPull() {
QString const s = c.getCommandResult().trimmed();
if (!s.isEmpty()) {
QStringList lines = Update::split(s, '\n');
worker()->CONSOLE(lines) << Worker::UPDATE_STEP::UPDATE_REPOSITORY;
if (!lines.empty()) {
int zoneNr = Utils::read1stLineOfFile("/mnt/system_data/zone_nr");
m_branchName = (zoneNr != 0) ? QString("zg1/zone%1").arg(zoneNr) : "master";
// lines can look like this:
// From https://git.mimbach49.de/GerhardHoffmann/customer_281
// 41ec581..5d25ac3 master -> origin/master
// ff10f57..43530a1 zg1/zone1 -> origin/zg1/zone1
// 6ed893f..5d9882c zg1/zone2 -> origin/zg1/zone2
// 4384d17..77045d8 zg1/zone3 -> origin/zg1/zone3
// 89d2812..36a0d74 zg1/zone5 -> origin/zg1/zone5
bool found = false;
for (int i=0; i < lines.size(); ++i) {
if (lines.at(i).contains(m_branchName)) {
found = true;
// 409f198..6c22726 zg1/zone1 -> origin/zg1/zone1
static QRegularExpression re("(^\\s*)([0-9A-Fa-f]+..[0-9A-Fa-f]+)(.*$)");
QRegularExpressionMatch match = re.match(lines.at(i));
if (match.hasMatch()) {
if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
return match.captured(2);
static const QRegularExpression alreadyUpToDate("^\\s*Already\\s+up\\s+to\\s+date.*$");
if (std::none_of(lines.cbegin(), lines.cend(),
[](QString const &s) { return s.contains(alreadyUpToDate); })) {
int zoneNr = Utils::read1stLineOfFile("/mnt/system_data/zone_nr");
m_branchName = (zoneNr != 0) ? QString("zg1/zone%1").arg(zoneNr) : "master";
// lines can look like this:
// From https://git.mimbach49.de/GerhardHoffmann/customer_281
// 41ec581..5d25ac3 master -> origin/master
// ff10f57..43530a1 zg1/zone1 -> origin/zg1/zone1
// 6ed893f..5d9882c zg1/zone2 -> origin/zg1/zone2
// 4384d17..77045d8 zg1/zone3 -> origin/zg1/zone3
// 89d2812..36a0d74 zg1/zone5 -> origin/zg1/zone5
bool found = false;
for (int i=0; i < lines.size(); ++i) {
if (lines.at(i).contains(m_branchName)) {
found = true;
// 409f198..6c22726 zg1/zone1 -> origin/zg1/zone1
static QRegularExpression re("(^\\s*)([0-9A-Fa-f]+..[0-9A-Fa-f]+)(.*$)");
QRegularExpressionMatch match = re.match(lines.at(i));
if (match.hasMatch()) {
if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
QString const matchCaptured = match.captured(2);
worker()->CONSOLE(QStringList(matchCaptured)) << Worker::UPDATE_STEP::UPDATE_REPOSITORY;
return matchCaptured;
} else {
QStringList lst(QString("(wrong capture count (%1)").arg(re.captureCount()));
worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
}
} else {
emit m_worker->showErrorMessage("git pull",
QString("(wrong cap-count (%1)").arg(re.captureCount()));
QStringList lst("no regex-match for commits");
worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
}
} else {
emit m_worker->showErrorMessage("git pull",
"no regex-match for commits");
Utils::printCriticalErrorMsg("NO REGEX MATCH FOR COMMITS");
}
}
}
if (!found) {
emit m_worker->showErrorMessage("git pull",
QString("unkown branch name ") + m_branchName);
Utils::printCriticalErrorMsg("UNKNOWN BRANCH NAME " + m_branchName);
if (!found) {
QStringList lst(QString("unknown branch name ") + m_branchName);
worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
}
} else {
return "Already up to date";
}
} else {
emit m_worker->showErrorMessage("git pull",
QString("wrong format for result of 'git pull' ") + s);
Utils::printCriticalErrorMsg(QString("WRONG FORMAT FOR RESULT OF 'GIT FETCH' ") + s);
QStringList lst(QString("WRONG FORMAT FOR RESULT OF 'GIT PULL' ") + s);
worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
}
} else {
// emit m_worker->showErrorMessage("git fetch", "empty result for 'git fetch'");
Utils::printInfoMsg("EMPTY RESULT FOR 'GIT PULL'");
QStringList lst("EMPTY RESULT FOR 'GIT PULL'");
worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
}
}
} else {
emit m_worker->showErrorMessage("git pull", QString("repository ") + m_customerRepository + " does not exist");
Utils::printCriticalErrorMsg(QString("REPOSITORY ") + m_customerRepository + " DOES NOT EXIST");
QStringList lst(QString("REPOSITORY ") + m_customerRepository + " DOES NOT EXIST");
worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
}
return std::nullopt;
}

View File

@@ -43,10 +43,15 @@ class GitClient : public QObject {
bool gitCloneAndCheckoutBranch();
Worker *worker() { return m_worker; }
Worker const *worker() const { return m_worker; }
std::optional<QString> gitPull();
std::optional<QStringList> gitDiff(QString const &commit);
std::optional<QStringList> gitMerge();
bool gitFsck();
QString gitLastCommit(QString fileName);
QStringList gitShowReason(QString branchName);
static QString gitBlob(QString fileName);

View File

@@ -56,7 +56,7 @@ void IsmasClient::printDebugMessage(int port,
QString const &clientIP,
int clientPort,
QString const &message) {
#if 1
#if 0
Q_UNUSED(port);
Q_UNUSED(clientIP);
Q_UNUSED(clientPort);
@@ -77,7 +77,7 @@ void IsmasClient::printInfoMessage(int port,
QString const &clientIP,
int clientPort,
QString const &message) {
#if 1
#if 0
Q_UNUSED(port);
Q_UNUSED(clientIP);
Q_UNUSED(clientPort);
@@ -315,7 +315,7 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
}
}
printInfoMessage(port, clientIP, clientPort, QString("MESSAGE RECEIVED ") + buf);
// printInfoMessage(port, clientIP, clientPort, QString("MESSAGE RECEIVED ") + buf);
QString response(buf);
if (int idx = response.indexOf("{\"error\":\"ISMAS is offline\"}")) {
@@ -390,16 +390,18 @@ QString IsmasClient::errorBackendNotConnected(QString const &info,
version.toStdString().c_str());
}
QString IsmasClient::errorGitClone(int percent, QString const &info, QString const &version) {
QString IsmasClient::errorGitClone(QString const &info,
QString const &version) {
return updateNewsToIsmas("U0003",
percent,
m_progressInPercent,
RESULT_CODE::INSTALL_ERROR,
"CLONE CUSTOMER REPOSITORY FAILED",
info.toStdString().c_str(),
version.toStdString().c_str());
}
QString IsmasClient::backendConnected(QString const &info, QString const &version) {
QString IsmasClient::backendConnected(QString const &info,
QString const &version) {
return updateNewsToIsmas("U0010",
m_progressInPercent,
RESULT_CODE::SUCCESS,
@@ -408,7 +410,8 @@ QString IsmasClient::backendConnected(QString const &info, QString const &versio
version.toStdString().c_str());
}
QString IsmasClient::execOpkgCommand(QString const &info, QString const &version) {
QString IsmasClient::execOpkgCommand(QString const &info,
QString const &version) {
return updateNewsToIsmas("U0010",
m_progressInPercent,
RESULT_CODE::SUCCESS,

View File

@@ -177,7 +177,7 @@ public:
QString cloneAndCheckoutCustomerRepository(QString const &info, QString const &version = QString()); // clone and checkout customer repository
QString checkoutBranch(QString const &info, QString const &version = QString()); // checkout branch
QString errorBackendNotConnected(QString const &info, QString const &version = QString()); // checkout branch
QString errorGitClone(int percent, QString const &info, QString const &version = QString());
QString errorGitClone(QString const &info, QString const &version = QString());
QString backendConnected(QString const &info, QString const &version = QString());
QString updateTriggerSet(QString const &info, QString const &version = QString());
QString errorUpdateTrigger(QString const &info, QString const &version = QString());

View File

@@ -64,24 +64,6 @@ 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();
@@ -101,6 +83,10 @@ int main(int argc, char *argv[]) {
pluginNameOption.setDefaultValue(pluginNameDefault);
parser.addOption(pluginNameOption);
QCommandLineOption noDownloadOption("no-psa-hardware-update",
QCoreApplication::translate("main", "Do not update the PSA firmware (json, device-controller)."));
parser.addOption(noDownloadOption);
QCommandLineOption workingDirectoryOption(QStringList() << "working-directory" << "working-directory",
QCoreApplication::translate("main", "working directory of update-script."),
QCoreApplication::translate("main", "directory"));
@@ -130,6 +116,7 @@ int main(int argc, char *argv[]) {
QString plugInName = parser.value(pluginNameOption);
QString workingDir = parser.value(workingDirectoryOption);
bool const dryRun = parser.isSet(dryRunOption);
bool const noUpdatePsaHardware = parser.isSet(noDownloadOption);
bool const showYoctoVersion = parser.isSet(yoctoVersionOption);
bool const showYoctoInstallStatus = parser.isSet(yoctoInstallStatusOption);
bool const showExtendedVersion = parser.isSet(extendedVersionOption);
@@ -170,6 +157,7 @@ int main(int argc, char *argv[]) {
qInfo() << "plugInName ..............." << plugInName;
qInfo() << "workingDir ..............." << workingDir;
qInfo() << "dryRun ..................." << dryRun;
qInfo() << "noUpdatePsaHardware ......" << noUpdatePsaHardware;
qInfo() << "extended-version ........." << APP_EXTENDED_VERSION;
//qInfo() << "yocto-version ............" << Worker::getATBUpdateToolYoctoVersion();
//qInfo() << "yocto-install-status ....." << Worker::getATBUpdateToolYoctoInstallationStatus();
@@ -181,35 +169,17 @@ int main(int argc, char *argv[]) {
#error "Only tested under UNIX/LINUX"
#endif
hwinf *hw = Update::loadDCPlugin(QDir(plugInDir), plugInName);
hw->dc_autoRequest(true);
// hw->dc_openSerial(5, "115200", "ttymxc2", 1);
Worker worker(customerNr,
machineNr,
zoneNr,
branchName,
plugInDir,
plugInName,
workingDir,
noUpdatePsaHardware,
dryRun);
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());
MainWindow mw(&worker);
worker.setMainWindow(&mw);
mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);

View File

@@ -13,102 +13,14 @@
#include <QEvent>
#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)
MainWindow::MainWindow(Worker *worker, QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_hw(hw)
, m_worker(worker)
, m_width(70)
, m_progressRunning(false)
, 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);
@@ -138,7 +50,7 @@ MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *paren
// ui->updateStatus->installEventFilter(this);
m_startTimer = new QTimer(this);
connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(update()));
connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(start()));
m_startTimer->setSingleShot(true);
m_startTimer->start(1000);
@@ -155,6 +67,8 @@ MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *paren
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(showErrorMessage(QStringList)),this, SLOT(onShowErrorMessage(QStringList)));
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)));
}
@@ -178,22 +92,22 @@ void MainWindow::customEvent(QEvent *event) {
case START_PROGRESS_LOOP: {
m_progressRunning = true;
ui->updateProgress->reset();
m_progressValue = 10;
QApplication::postEvent(this, new ProgressEvent(this, m_progressValue));
// m_progressValue = 10;
QApplication::postEvent(this, new ProgressEvent(this, 1));
} break;
case STOP_PROGRESS_LOOP: {
m_progressRunning = false;
m_progressValue -= 10;
m_worker->setProgress(m_progressValue/10);
// m_progressValue -= 10;
// m_worker->setProgress(m_progressValue/10);
} break;
default: {
if (m_progressRunning) {
m_progressValue = progress;
ui->updateProgress->setValue(progress/10);
QApplication::postEvent(this, new ProgressEvent(this, progress+10));
QThread::msleep(500);
}
}
if (m_progressRunning) {
// m_progressValue = progress;
ui->updateProgress->setValue(progress);
// ueberpruefen: hauptfenster schickt sich selber ein event
// QApplication::postEvent(this, new ProgressEvent(this, progress));
// QThread::msleep(500);
}}
}
} else
if (sender == m_worker) {
@@ -213,86 +127,6 @@ 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();
@@ -310,13 +144,6 @@ void MainWindow::onEnableExit() {
ui->exit->setEnabled(true);
}
//bool MainWindow::eventFilter(QObject *obj, QEvent *ev) {
// if (obj == ui->updateStatus) {
// qCritical() << "REc. event for text edit" << ev->type();
// }
// return QMainWindow::eventFilter(obj, ev);
//}
void MainWindow::onRestartExitTimer() {
m_exitTimer->stop();
m_exitTimer->start(60 * 1000);
@@ -327,8 +154,18 @@ void MainWindow::onRestartExitTimer() {
void MainWindow::onQuit() {
m_exitTimer->stop();
qCritical() << QString("ON QUIT: EXIT CODE %1").arg(m_worker->returnCode());
qApp->exit(m_worker->returnCode());
int errorCode = 0;
qCritical()
<< QString("ON QUIT: CURRENT STEP %1")
.arg(m_worker->getSmap()[m_worker->currentStep()]);
// TODO: replace SEND_LAST_VERSION with UPDATE_SUCCEEDED
if (m_worker->currentStep() != Worker::UPDATE_STEP::SEND_LAST_VERSION) {
errorCode = -1;
}
qCritical() << QString("ON QUIT: EXIT CODE %1").arg(errorCode);
qApp->exit(errorCode);
}
void MainWindow::scrollDownTextEdit() {
@@ -448,3 +285,21 @@ void MainWindow::onShowErrorMessage(QString title, QString text) {
void MainWindow::onShowStatusMessage(QString title, QString text) {
onShowMessage(title, text);
}
void MainWindow::onShowErrorMessage(QStringList lst) {
if (lst.size() >= 2) {
onShowMessage(lst.at(0), lst.at(1));
}
if (lst.size() == 1) {
onShowMessage(lst.at(0), "");
}
}
void MainWindow::onShowStatusMessage(QStringList lst) {
if (lst.size() >= 2) {
onShowMessage(lst.at(0), lst.at(1));
}
if (lst.size() == 1) {
onShowMessage(lst.at(0), "");
}
}

View File

@@ -21,10 +21,9 @@ class MainWindow : public QMainWindow {
protected:
void customEvent(QEvent *event) override;
// bool eventFilter(QObject *obj, QEvent *ev) override;
public:
MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *parent = nullptr);
MainWindow(Worker *worker, QWidget *parent = nullptr);
~MainWindow();
static const int START_PROGRESS_LOOP = -1;
@@ -34,11 +33,6 @@ public:
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; }
@@ -48,6 +42,8 @@ public slots:
void onReplaceLast(QString, QString suffix = "");
void onShowErrorMessage(QString, QString);
void onShowStatusMessage(QString, QString);
void onShowErrorMessage(QStringList);
void onShowStatusMessage(QStringList);
void onStopStartTimer();
void onRestartExitTimer();
void onEnableExit();
@@ -70,14 +66,12 @@ private:
void onShowMessage(QString, QString);
Ui::MainWindow *ui;
hwinf *m_hw;
Worker *m_worker;
int const m_width;
QTimer *m_startTimer;
QTimer *m_exitTimer;
bool m_progressRunning;
int m_progressValue;
Update *m_update;
//int m_progressValue;
UpdateDcEvent::UpdateStep m_updateStep;
};
#endif // MAINWINDOW_H

View File

@@ -344,7 +344,41 @@ struct T_devices
};
struct T_chg_Tub
{
uint8_t tubeLevel[8]; // [0]=nr coins of lowest value
uint8_t tubeFull[8]; // 1=full 0 else
uint16_t tubeValues[8]; // in cent [0]=lowest value 5c or 10cent
uint16_t tubeFilled[8]; // nr of every coin inserted
uint16_t tubeDispens[8]; // nr of every coin dispensed
// 64 byte
};
struct T_changer
{
// Fixdata from Coin Changer
uint8_t setup; // always 1
uint8_t state; // step of state machine
// 0..12 like EMP, 13...30 for coin dispense
uint8_t level; // mdb-level, always 3
uint16_t countryCode;
uint8_t scale;
uint8_t decimals;
uint8_t coinSetup[16]; // [0]=lowest coin, multiply with scale
uint16_t intendedAcceptance; //bitwise 0,1 1=accept coin, came from master
uint8_t tokenChannel;
uint8_t pollingRunning; // 1: emp is polled 0:not
uint8_t paymentRunning; // 1: coins are accepted
uint16_t denomination[16];
uint16_t availableTubes; //bitwise 0,1 1=av. bit0 = lowest coin value
};
struct T_bna
{
};
class hwinf
{
@@ -1373,7 +1407,183 @@ public:
virtual void mif_getAtbCardExpire(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute) const =0;
// ------------------------------------------------------------------------------------
// Device-Controller-Bootloader convenient version 21.09.2023
// ------------------------------------------------------------------------------------
// use this to jump to BL:
//void hwapi::bl_rebootDC(void) const
// use this to start BL:
// void hwapi::bl_startBL(void) const
// call this in order to get response from BL:
//void hwapi::bl_checkBL(void) const
// evaluate BL response:
//bool hwapi::bl_isUp(void) const
// 29.9.23: new: "completeStart" function, replaces bl_rebootDC(), bl_startBL() and bl_checkBL()
// result can be verified with bl_isUp() as before
virtual bool bl_completeStart(void) const =0;
// must be used in DC's normal operation
// select binfile-name in GUI
// send binfile-name to BL-processor:
virtual bool bl_storeFirmware(QString fileName) const =0;
// load binary file 3x and compare
// return true if loaded correctly
// return false: error, could not load correctly
// request the number of blocks for this file
virtual uint16_t bl_getNrOfFirmwareBlocks(void) const =0;
// size of the loaded bin file in 64byte blocks
// call after bl_storeFirmware()
// call the next two function's repetitive with "blockNumber"=0,1,2,3....."bl_getNrOfFirmwareBlocks()"
virtual bool bl_blockAutoLoad(uint16_t blockNumber) const =0;
// call in loop from block number 0 up to <= "dcBL_getNrOfBlocks()"
//the last block "bl_getNrOfFirmwareBlocks()" is sent as conclusion command (important!)
// but after every call WAIT (!) for response "bl_blockAutoResponse()" !!!!
// data will be sent to DC, if neccesary addr will be sent additionally
// if neccesary sending will automatically repeat up to 3times
// retval: false if blockNumber>4095, true else
// check out this response after every block-sending, wait until >0!!!
virtual int8_t bl_blockAutoResponse(void) const =0;
// after every "bl_blockAutoLoad()" call this until response
// retval 0: wait 1: OK, blk was sent 2: OK, transfer complete
// 3: error despite repeating, cancel. probably bin file corrupted
// Max duration: 3x no response from BL = 900ms
// finally call:
// void hwapi::bl_stopBL(void) const
// -------------- end of bootloader ---------------------------------------------------
// new from 28.9.23 and earliest from DC version 4.45
// get all versions of the DC-Jsons
virtual void sys_requestJsonVersions(uint8_t jsonNr) const =0;
// send one request for every single version
// jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res.
// 5=printer template 1 ..... 36= template 32
virtual void sys_getJsonVersions(uint8_t jsonNr, char *versionString) const =0;
// jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res.
// 5=printer template 1 ..... 36= template 32
// length of buffer is always 16 byte
// ------------------------------------------------------------------------------------
// Coin Changer
// ------------------------------------------------------------------------------------
// find above (same as for coin checker (EMP)):
// mdb_switchPower(true); // power on/off
// cash_startPayment(amount_cent); // start polling, enable coins, changer turns to green
// getInsertedAmount()
// getLastInsertedCoin()
// getAllInsertedCoins(uint16_t *types, uint16_t *values)
// all inserted coins of this past transaction are stored, max 64
// cash_stopPayment(); // and wait for further command (changer blinks yellow)
// cash_cancelPayment(); // and return complete paid amount
// after ticket/goods issue:
// vend_success()
// conclude payment process, keep all coins. Printing was successful
// return change (payment above start-amount), so it works only if
// Payment was started with real vending price (pre selection).
// if payment was started with maximum price (for direct coin insertion)
// then use "changer_returnCoins()", not vend_success()
// vend_failed()
// conclude payment process and return complete paid amount
// also valid for changer:
// emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const =0;
// coinAcceptance: bit0=coin1 (lowest donomination) bit15=coin16 bitH=accept bit L = deny coin (no validation)
// tokenChannel 0...31: if this signal comes from emp then a token was inserted
// coinDenomination = array of 16 coin values (e.g. 5, 10, 20...)
virtual void changer_returnCoins(uint32_t amountInCent) const =0;
virtual void changer_requestChangeResult(void) const =0;
virtual uint8_t changer_getChangeResult(uint32_t *returnedAmount) const =0;
// get result of coin dispensing
// receivedData[0]: 0: not yet started 1:amount returned
// 2:only partial return 3: no return possible
// receivedData[2,3,4,5]: returned amount
virtual void changer_getAllParameters(struct T_changer *mw) const =0;
// requested automatically with 23, same like EMP
virtual void changer_requestTubelevel(void) const =0;
virtual void changer_getTubelevel(struct T_chg_Tub *tubLevel) const =0;
// don't use tubeDispens[], it's not yet correct!
// ------------------------------------------------------------------------------------
// bank note acceptor
// ------------------------------------------------------------------------------------
// already defiened functions applying for BNA as well:
// mdb_switchPower(true); // power on/off
// bank notes are integrated in the normal transaction process, so use the usual functions to run a vending cycle:
// cash_startPayment(amount_cent); // start polling, enable bills, reader shows green
// getInsertedAmount()
// cash_stopPayment();
// cash_cancelPayment();
// vend_success()
// vend_failed()
virtual void bna_sendSettings(uint16_t notesToAccept, uint16_t parameters,
uint16_t *billDenomination,
uint32_t acceptanceLimit) const =0;
// notesToAccept: bit0=bill1 (lowest donomination) bitH=accept bit L = deny
// parameters: e.g. use escrow function for some notes
// billDenomination = array of 16 bill values (e.g. 5, 10, 20...)
// these can be set alternatively by Json-File DC2C_cash.json
// acceptanceLimit: device will stop acceptance once this amount is reached and
// optionally keep last bill in escrow until vend_success()
// is called (put bill to stacker) or vend_failed() is called (return bill)
virtual void bna_setCurrentAcceptance(uint16_t notesToAccept) const =0;
// can be used to block notes dynamically, example: from now only 5€ bills are allowed (if only 3€ are to be paid)
// only valid till next start-payment. Cannot add notes which are not activated in Json
virtual void bna_requestParameters(void) const =0;
// send command to DC in order to get static invariable device parameters like currency
// device must be powered and polled to get these
virtual bool bna_getAllParameters(struct T_bna *bna) const =0;
// get all constant data from reader (e.g. currency)
// and actual Host-Settings (sent with bna_sendSettings() or json)
// retval = true if data are valid
virtual void bna_requestCurrentNotes(void) const =0;
// send command to DC in order to get transaction data
virtual uint8_t bna_getCurrentNotes(uint16_t latestBill, uint16_t *currentNotes) const =0;
// returns number of collected bank notes since start-command (current transaction)
// latestBill: last accepted bank note, value in cent
// currentNotes an array with up to 16 (further) notes collected
virtual void bna_requestStackerLevel(void) const =0;
virtual uint16_t bna_getStackerLevel(uint32_t *amountInStacker, uint16_t *countOfBills) const =0;
// return val: nr of bills in stacker
// countOfBills: array of up to 16 sums, countOfBills[0]=nr of 5€-bills in stacker
// countOfBills[1] for 10€ and so on
@@ -1395,8 +1605,6 @@ signals:
virtual void hwapi_payCancelled(void) const=0;
virtual void hwapi_coinProcessJustStopped(void) const=0;
// new from 2023.06.12
virtual void hwapi_doorServiceDoorOpened(void) const=0;
virtual void hwapi_doorVaultDoorOpened(void) const=0;
virtual void hwapi_doorCoinBoxRemoved(void) const=0;
@@ -1454,9 +1662,17 @@ signals:
// 18.9.2023 major improvements for DC data exchange
// verification of door and cash box signals
// intensive verification of Json-Programming Master-Slave (PTU to DC), 100% ok
#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.6"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.6"
// 20.9.2023: speeding up door and cash box signals
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.7"
// 26.09.2023: added improved DC-bootloader files
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.8"
// 28.09.2023: added version request of DC-Json-Files
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/5.0"
// 10.10.2023: added coin changer
#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/5.1"
// 20.10.2023: added bill validator
Q_DECLARE_INTERFACE(hwinf, HWINF_iid)

Binary file not shown.

View File

@@ -4,6 +4,7 @@
#include <QDebug>
#include <QDir>
#include <QRegularExpression>
#include <QDateTime>
Command::Command(QString const &command, int start_timeout, int finish_timeout)
: m_command(command.trimmed())
@@ -65,6 +66,8 @@ bool Command::execute(QString workingDirectory, QStringList args) {
p->start(m_command);
}
qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch();
if (p->waitForStarted(m_waitForStartTimeout)) {
qDebug() << "PROCESS" << m_command << "STARTED IN" << p->workingDirectory();
if (p->state() == QProcess::ProcessState::Running) {
@@ -80,31 +83,41 @@ bool Command::execute(QString workingDirectory, QStringList args) {
qDebug() << "PROCESS" << m_command << "FINISHED IN" << p->workingDirectory();
if (p->exitStatus() == QProcess::NormalExit) {
if ((m_exitCode = p->exitCode()) == 0) {
qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
qDebug() << "EXECUTED" << m_command
<< QString("(runtime %1ms)").arg(end-start)
<< "with code" << m_exitCode
<< "IN" << p->workingDirectory();
return true;
} else {
qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
qCritical() << "EXECUTED" << m_command
<< QString("(runtime %1ms)").arg(end-start)
<< "with code" << m_exitCode
<< "IN" << p->workingDirectory();
}
} else {
qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
qCritical() << "PROCESS" << m_command << "CRASHED with code"
<< p->exitCode()
<< QString("(after %1ms)").arg(end-start)
<< "IN" << p->workingDirectory();
}
} else {
qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
qCritical() << "PROCESS" << m_command
<< "DID NOT FINISH WITH" << wait
<< "MS IN" << p->workingDirectory();
<< "MS IN" << p->workingDirectory()
<< QString("(runtime %1ms)").arg(end-start);
}
} else {
qCritical() << "WRONG PROCESS STATE" << p->state()
<< "IN" << p->workingDirectory();
}
} else {
qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
qCritical() << "PROCESS" << m_command << "TIMEOUT AT START"
<< QString("(runtime %1ms)").arg(end-start)
<< "IN" << p->workingDirectory();
}
return false;

View File

@@ -94,11 +94,11 @@ bool Update::unloadDCPlugin() {
return false;
}
Update::Update(hwinf *hw,
Worker *worker,
Update::Update(Worker *worker,
QString customerRepository,
QString customerNrStr,
QString branchName,
QString plugInDir,
QString pluginName,
QString workingDir,
bool dryRun,
@@ -106,7 +106,7 @@ Update::Update(hwinf *hw,
char const *serialInterface,
char const *baudrate)
: QObject(parent)
, m_hw(hw)
, m_hw(loadDCPlugin(QDir(plugInDir), pluginName))
, m_worker(worker)
, m_serialInterface(serialInterface)
, m_baudrate(baudrate)
@@ -742,7 +742,17 @@ QStringList Update::getDcSoftAndHardWareVersion() {
}
bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
// always assume that serial line is open
int tries = 20;
while (!m_hw->sys_areDCdataValid()) { // must deliver 'true', only then are all
// data from hwapi valid
if (--tries < 0) {
qCritical() << "ERROR!!! DC DATA NOT VALID -> CA-MASTER-PLUGIN NOT CONNECTED";
return false;
}
m_hw->dc_autoRequest(true);
QThread::msleep(500);
}
bool res = false;
QList<QString>::const_iterator it;
for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
@@ -846,8 +856,8 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
res = false;
}
m_worker->stopProgressLoop();
m_worker->setProgress(100);
// m_worker->stopProgressLoop();
// m_worker->setProgress(100);
if (res == false) {
break;

View File

@@ -21,8 +21,8 @@ class Worker;
class Update : public QObject {
Q_OBJECT
hwinf *m_hw;
Worker *m_worker;
hwinf *m_hw = nullptr;
Worker *m_worker = nullptr;
char const *m_serialInterface;
char const *m_baudrate;
QString m_customerRepository;
@@ -44,11 +44,11 @@ public:
static QStringList split(QString line, QChar sep = ',');
explicit Update(hwinf *hw,
Worker *worker,
explicit Update(Worker *worker,
QString customerRepository,
QString customerNrStr,
QString branchName,
QString plugInDir,
QString pluginName,
QString workingDir,
bool dryRun = false,
@@ -58,6 +58,9 @@ public:
virtual ~Update() override;
bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn);
hwinf *hw() { return m_hw; }
hwinf const *hw() const { return m_hw; }
//QString customerId() { return m_customerId; }
//QString const customerId() const { return m_customerId; }

View File

@@ -46,10 +46,12 @@ QString Utils::zoneName(quint8 i) {
return "N/A";
}
void Utils::printCriticalErrorMsg(QString const &errorMsg) {
qCritical() << QString(80, 'E');
void Utils::printCriticalErrorMsg(QString const &errorMsg, bool upper, bool lower) {
if (upper) qCritical() << QString(80, 'E');
qCritical() << errorMsg;
qCritical() << QString(80, 'E');
if (lower) qCritical() << QString(80, 'E');
}
void Utils::printCriticalErrorMsg(QStringList const &errorMsg) {
@@ -60,32 +62,74 @@ void Utils::printCriticalErrorMsg(QStringList const &errorMsg) {
qCritical() << QString(80, 'E');
}
void Utils::printUpdateStatusMsg(QDebug debug, QStringList const &updateMsg) {
//if (updateMsg.size() > 1) {
// qCritical() << QString(80, 'U');
//}
Q_UNUSED(debug);
for (int i = 0; i < updateMsg.size(); ++i) {
qInfo() << updateMsg.at(i);
}
//if (updateMsg.size() > 1) {
// qCritical() << QString(80, 'U');
//}
}
void Utils::printUpdateStatusMsg(QStringList const &updateMsg) {
qCritical() << QString(80, 'U');
//if (updateMsg.size() > 1) {
// qCritical() << QString(80, 'U');
//}
for (int i = 0; i < updateMsg.size(); ++i) {
qCritical() << updateMsg.at(i);
}
qCritical() << QString(80, 'U');
//if (updateMsg.size() > 1) {
// qCritical() << QString(80, 'U');
//}
}
void Utils::printUpdateStatusMsg(QString const &updateMsg) {
qCritical() << QString(80, 'U');
void Utils::printUpdateStatusMsg(QString const &updateMsg, bool upper, bool lower) {
if (upper) qCritical() << QString(80, 'U');
qCritical() << updateMsg;
qCritical() << QString(80, 'U');
if (lower) qCritical() << QString(80, 'U');
}
void Utils::printInfoMsg(QString const &infoMsg) {
qCritical() << QString(80, 'I');
void Utils::printUpdateStatusMsg(QDebug debug, QString const &updateMsg,
bool upper, bool lower) {
if (upper) debug << QString(80, 'U');
qInfo() << updateMsg;
if (lower) debug << QString(80, 'U');
}
void Utils::printInfoMsg(QString const &infoMsg, bool upper, bool lower) {
if (upper) qCritical() << QString(80, 'I');
qCritical() << infoMsg;
qCritical() << QString(80, 'I');
if (lower) qCritical() << QString(80, 'I');
}
void Utils::printInfoMsg(QStringList const &infoMsg) {
qCritical() << QString(80, 'I');
//if (infoMsg.size() > 1) {
// qCritical() << QString(80, 'I');
//}
for (int i = 0; i < infoMsg.size(); ++i) {
qCritical() << infoMsg.at(i);
}
qCritical() << QString(80, 'I');
//if (infoMsg.size() > 1) {
// qCritical() << QString(80, 'I');
//}
}
void Utils::printLineEditInfo(QStringList const &lines) {

View File

@@ -8,16 +8,19 @@
#include <QFileInfo>
#include <QDateTime>
#include <QDir>
#include <QDebug>
namespace Utils {
int read1stLineOfFile(QString fileName);
QString zoneName(quint8 i);
void printCriticalErrorMsg(QString const &errorMsg);
void printCriticalErrorMsg(QString const &errorMsg, bool upper=false, bool lower=false);
void printCriticalErrorMsg(QStringList const &errorMsg);
void printInfoMsg(QString const &infoMsg);
void printInfoMsg(QString const &infoMsg, bool upper=false, bool lower=false);
void printInfoMsg(QStringList const &infoMsg);
void printUpdateStatusMsg(QDebug debug, QStringList const &updateMsg);
void printUpdateStatusMsg(QStringList const &updateMsg);
void printUpdateStatusMsg(QString const &updateMsg);
void printUpdateStatusMsg(QString const &updateMsg, bool upper=false, bool lower=false);
void printUpdateStatusMsg(QDebug debug, QString const &updateMsg, bool upper=false, bool lower=false);
void printLineEditInfo(QStringList const &lines);
QString getTariffLoadTime(QString fileName);
QString rstrip(QString const &str);

1502
worker.cpp

File diff suppressed because it is too large Load Diff

1138
worker.h

File diff suppressed because it is too large Load Diff